ServerCfg.go 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. package zsshrpc_server
  2. import (
  3. "crypto/rand"
  4. "crypto/rsa"
  5. "crypto/x509"
  6. "encoding/pem"
  7. "errors"
  8. "golang.org/x/crypto/ssh"
  9. "io/ioutil"
  10. "os"
  11. )
  12. type PasswdCb func(conn ssh.ConnMetadata, password []byte) (*ssh.Permissions, error)
  13. type PubKeyCb func(conn ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error)
  14. type KeyIntCb func(conn ssh.ConnMetadata, cli ssh.KeyboardInteractiveChallenge) (*ssh.Permissions, error)
  15. type AuthLogCb func(conn ssh.ConnMetadata, method string, err error)
  16. type SvrLogFunc func(level int, msg string, err error)
  17. type ZSshRpcServerCfg struct {
  18. HostKey ssh.Signer
  19. NoClientAuth bool
  20. MaxAuthTries int
  21. PasswordCallback PasswdCb
  22. PublicKeyCallback PubKeyCb
  23. KeyboardInteractiveCallback KeyIntCb
  24. AuthLogCallback AuthLogCb
  25. ServerLogger SvrLogFunc
  26. Support_AES128_CBC bool
  27. OperationHandler ZSshRpcOperationHandler
  28. IOBlockSize int
  29. }
  30. func NewDefaultZSshRpcServerCfg(host_key_store_path string) (*ZSshRpcServerCfg, error) {
  31. hostkey, err := GetOrGenerateHostKey(host_key_store_path, 2028)
  32. if err != nil {
  33. return nil, err
  34. }
  35. return &ZSshRpcServerCfg{
  36. HostKey: hostkey,
  37. NoClientAuth: false,
  38. MaxAuthTries: 5,
  39. PasswordCallback: defaultPasswordCallback,
  40. PublicKeyCallback: defaultPubkeyCallback,
  41. KeyboardInteractiveCallback: defaultKeyIntCallback,
  42. AuthLogCallback: defaultAuthLogCb,
  43. ServerLogger: defaultServerLoggerFunc,
  44. Support_AES128_CBC: true,
  45. OperationHandler: &defaultOperationHandler{},
  46. IOBlockSize: 1024,
  47. }, nil
  48. }
  49. func defaultPasswordCallback(conn ssh.ConnMetadata, passwd []byte) (*ssh.Permissions, error) {
  50. return nil, errors.New("method not support")
  51. }
  52. func defaultPubkeyCallback(conn ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) {
  53. return nil, errors.New("method not support")
  54. }
  55. func defaultKeyIntCallback(conn ssh.ConnMetadata, cli ssh.KeyboardInteractiveChallenge) (*ssh.Permissions, error) {
  56. return nil, errors.New("method not support")
  57. }
  58. func defaultAuthLogCb(conn ssh.ConnMetadata, method string, err error) {
  59. }
  60. type defaultOperationHandler struct {
  61. }
  62. func (this *defaultOperationHandler) HandleOperation(request ZSshRpcOperationRequest) ZSshRpcOperationResponse {
  63. return ZSshRpcOperationResponse{
  64. StatusCode: ResponseStatusCode_NOT_FOUND,
  65. ResponseJSON: "{}",
  66. }
  67. }
  68. func defaultServerLoggerFunc(level int, msg string, err error) {
  69. }
  70. func (this *ZSshRpcServerCfg) UsePasswordAuth(callback PasswdCb) {
  71. this.PasswordCallback = callback
  72. }
  73. func (this *ZSshRpcServerCfg) UsePublicKeyAuth(callback PubKeyCb) {
  74. this.PublicKeyCallback = callback
  75. }
  76. func (this *ZSshRpcServerCfg) UseKeyboardInteractiveAuth(callback KeyIntCb) {
  77. this.KeyboardInteractiveCallback = callback
  78. }
  79. func (this *ZSshRpcServerCfg) UseAuthLogger(callback AuthLogCb) {
  80. this.AuthLogCallback = callback
  81. }
  82. func (this *ZSshRpcServerCfg) UseLogger(logfunc SvrLogFunc) {
  83. this.ServerLogger = logfunc
  84. }
  85. func (this *ZSshRpcServerCfg) SetHandler(handler ZSshRpcOperationHandler) {
  86. this.OperationHandler = handler
  87. }
  88. func GetOrGenerateHostKey(key_store_path string, key_length_to_gen int) (ssh.Signer, error) {
  89. if IsFileExists(key_store_path) {
  90. hostkeydata, err := ioutil.ReadFile(key_store_path)
  91. if err != nil {
  92. return generateHostKey(key_store_path, key_length_to_gen)
  93. }
  94. hostkey, err := ssh.ParsePrivateKey(hostkeydata)
  95. if err != nil {
  96. return generateHostKey(key_store_path, key_length_to_gen)
  97. }
  98. return hostkey, nil
  99. } else {
  100. return generateHostKey(key_store_path, key_length_to_gen)
  101. }
  102. }
  103. func generateHostKey(keypath string, len int) (ssh.Signer, error) {
  104. prikey, err := rsa.GenerateKey(rand.Reader, len)
  105. if err != nil {
  106. return nil, err
  107. }
  108. privateKeyFile, err := os.Create(keypath)
  109. defer privateKeyFile.Close()
  110. if err != nil {
  111. return nil, err
  112. }
  113. privateKeyPEM := &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(prikey)}
  114. if err := pem.Encode(privateKeyFile, privateKeyPEM); err != nil {
  115. return nil, err
  116. }
  117. hostkeydata, err := ioutil.ReadFile(keypath)
  118. if err != nil {
  119. return nil, err
  120. }
  121. hostkey, err := ssh.ParsePrivateKey(hostkeydata)
  122. if err != nil {
  123. return nil, err
  124. }
  125. return hostkey, nil
  126. }