SSHServer.go 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. package SSHServer
  2. import (
  3. "git.swzry.com/NSMCServerLauncher/Utils"
  4. "fmt"
  5. "git.swzry.com/NSMCServerLauncher/Logger"
  6. "crypto/rsa"
  7. "crypto/rand"
  8. "crypto/x509"
  9. "encoding/pem"
  10. "os"
  11. "golang.org/x/crypto/ssh"
  12. "io/ioutil"
  13. "net"
  14. "github.com/swzry/go.TSmap"
  15. "golang.org/x/crypto/ssh/terminal"
  16. "git.swzry.com/NSMCServerLauncher/Terminal"
  17. "golang.org/x/crypto/bcrypt"
  18. )
  19. var mainThreadBlockChan chan byte
  20. var ServerConf *ssh.ServerConfig
  21. var _clientListRawMap map[interface{}]interface{}
  22. var ClientList TSmap.TSmap
  23. func StartSSHServer(mtbc chan byte) {
  24. mainThreadBlockChan = mtbc
  25. if r,err := Utils.PathExists(SSHServerConf.host_key_file); ((!r) || (err != nil)) {
  26. fmt.Fprintln(&Logger.Log.SysInfo,"Generating SSH Host Key......")
  27. fmt.Fprintln(&Logger.Log.SysInfo,"(It may takes a long time. Please wait.)")
  28. fmt.Println("Generating SSH Host Key......")
  29. fmt.Println("(It may takes a long time. Please wait.)")
  30. GenerateRSAKey(SSHServerConf.host_key_file, SSHServerConf.defult_key_length)
  31. }
  32. ServerConf = &ssh.ServerConfig{
  33. NoClientAuth: false,
  34. MaxAuthTries: SSHServerConf.max_auth_tries,
  35. PasswordCallback: SSHPasswordCallback,
  36. PublicKeyCallback: SSHPublicKeyCallback,
  37. AuthLogCallback: SSHAuthLogCallback,
  38. ServerVersion: "SSH-2.0-NSMCServerLauncher-SSH",
  39. }
  40. keyBytes, err := ioutil.ReadFile(SSHServerConf.host_key_file)
  41. if(err != nil){
  42. fmt.Fprintln(&Logger.Log.SysFatal,"Failed to Load Host Key File: ", err)
  43. mainThreadBlockChan <- 1
  44. return
  45. }
  46. key, err := ssh.ParsePrivateKey(keyBytes)
  47. if(err != nil){
  48. fmt.Fprintln(&Logger.Log.SysFatal,"Failed to Load Host Key: ", err)
  49. mainThreadBlockChan <- 1
  50. return
  51. }
  52. ServerConf.AddHostKey(key)
  53. listener,err := net.Listen("tcp", SSHServerConf.bind_addr)
  54. if(err != nil){
  55. fmt.Fprintln(&Logger.Log.SysFatal,"Failed to Bind Address '",SSHServerConf.bind_addr,"': ", err)
  56. mainThreadBlockChan <- 1
  57. return
  58. }
  59. fmt.Fprintln(&Logger.Log.SysInfo,"Listening At '",listener.Addr().String(),"'.")
  60. _clientListRawMap = make(map[interface{}]interface{})
  61. ClientList = &TSmap.NewTSmap{
  62. ConMap:_clientListRawMap,
  63. }
  64. for{
  65. tcpConn,err := listener.Accept()
  66. if(err == nil){
  67. fmt.Fprintf(&Logger.Log.SSH,"New Client '%v' Entered.\n",tcpConn.RemoteAddr())
  68. _, schan, reqchan, err := ssh.NewServerConn(tcpConn, ServerConf)
  69. if(err != nil){
  70. fmt.Fprintf(&Logger.Log.SSH,"Failed Handle Client '%v': %v\n",tcpConn.RemoteAddr(),err)
  71. tcpConn.Close()
  72. continue
  73. }else {
  74. ClientList.Set(tcpConn,&Utils.ClientConnection{
  75. Channels: &TSmap.NewTSmap{
  76. ConMap:make(map[interface{}]interface{}),
  77. },
  78. })
  79. go ssh.DiscardRequests(reqchan)
  80. go handleChannels(schan, tcpConn)
  81. }
  82. }
  83. }
  84. }
  85. func handleChannels(ch <-chan ssh.NewChannel, conn net.Conn) {
  86. cnt := 0
  87. chlist,ok := ClientList.Get(conn)
  88. if(!ok){
  89. fmt.Fprintf(&Logger.Log.SSH,"Failed Handle Client '%v': Channels Not Found.\n",conn.RemoteAddr())
  90. }
  91. for newchan := range ch {
  92. cnt++;
  93. fmt.Fprintf(&Logger.Log.SSH,"Client '%v', Channels %v, Handling.\n",conn.RemoteAddr(),cnt)
  94. go handleChannel(newchan,conn,cnt,chlist.(*Utils.ClientConnection))
  95. }
  96. }
  97. func handleChannel(nch ssh.NewChannel,conn net.Conn,num int,chlist *Utils.ClientConnection) {
  98. if(nch.ChannelType() == "session"){
  99. ch,req,err := nch.Accept()
  100. if(err != nil){
  101. fmt.Fprintf(&Logger.Log.SSH,"Client '%v', Channels %v, Failed Handling : %v\n",conn.RemoteAddr(),num,err)
  102. return
  103. }else{
  104. r:= <-req
  105. r.Reply(true,nil)
  106. chlist.Channels.Set(num,Utils.AvaliableChannel{
  107. Channel: ch,
  108. Term: terminal.NewTerminal(ch,"NSMC >"),
  109. UserContext: Utils.UserContextType{
  110. PWD: "/",
  111. },
  112. })
  113. go Terminal.HandlerTerminal(ClientList,conn, num)
  114. }
  115. }else{
  116. nch.Reject(ssh.UnknownChannelType, "Unknown Channel Type")
  117. fmt.Fprintf(&Logger.Log.SSH,"Client '%v', Channels %v, Rejected : Unknown Channel Type '%v'\n",conn.RemoteAddr(),num,nch.ChannelType())
  118. }
  119. }
  120. func SSHPasswordCallback(conn ssh.ConnMetadata, password []byte) (*ssh.Permissions, error) {
  121. val, ok := SSHServerConf.passwd[conn.User()]
  122. if(!ok){
  123. fmt.Fprintf(&Logger.Log.SSH,"Client '%v' Auth Failed : Unknown User '%v'\n",conn.RemoteAddr(),conn.User())
  124. return nil,fmt.Errorf("Password Error or User '%v' Does Not Exist..",conn.User())
  125. }
  126. err := bcrypt.CompareHashAndPassword([]byte(val),password)
  127. if(err != nil){
  128. fmt.Fprintf(&Logger.Log.SSH,"Client '%v', User '%v', Auth Failed : Password Error, Detail: '%v'\n",conn.RemoteAddr(),conn.User(),err)
  129. return nil,fmt.Errorf("Password Error or User '%v' Does Not Exist..",conn.User())
  130. }
  131. return nil,nil
  132. }
  133. func SSHPublicKeyCallback(conn ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error){
  134. return nil,fmt.Errorf("PublicKey Auth Not Support Yet.")
  135. }
  136. func SSHAuthLogCallback(conn ssh.ConnMetadata, method string, err error){
  137. fmt.Fprintf(&Logger.Log.SSH,"AuthFailed. Info: client='%v', user='%v', method='%v'. Err: %v\n",conn.RemoteAddr(),conn.User(),method,err)
  138. }
  139. func GenerateRSAKey(keyfn string,keyLength int) {
  140. privateKey, err := rsa.GenerateKey(rand.Reader, keyLength)
  141. if err != nil {
  142. fmt.Fprintln(&Logger.Log.SysFatal,"Failed to Generate RSA Private Key: ", err)
  143. mainThreadBlockChan <- 1
  144. return
  145. }
  146. derStream := x509.MarshalPKCS1PrivateKey(privateKey)
  147. block := &pem.Block{
  148. Type: "RSA PRIVATE KEY",
  149. Bytes: derStream,
  150. }
  151. file, err := os.Create(keyfn)
  152. if err != nil {
  153. fmt.Fprintln(&Logger.Log.SysFatal,"Failed to Create Key File: ", err)
  154. mainThreadBlockChan <- 1
  155. return
  156. }
  157. err = pem.Encode(file, block)
  158. if err != nil {
  159. fmt.Fprintln(&Logger.Log.SysFatal,"Failed to Encode Key: ", err)
  160. mainThreadBlockChan <- 1
  161. return
  162. }
  163. fmt.Fprintln(&Logger.Log.SysInfo,"SSH Host Key Generated Successfully..")
  164. fmt.Println("SSH Host Key Generated Successfully..")
  165. }