Commit 747900d3 authored by ibuler's avatar ibuler

[Update] 提交1

parent 17a481d4
package main package main
import ( import (
"cocogo/pkg/auth"
"cocogo/pkg/config" "cocogo/pkg/config"
"cocogo/pkg/sshd" "cocogo/pkg/sshd"
) )
func init() { func init() {
config.Initial() config.Initial()
auth.Initial()
sshd.Initial()
} }
func main() { func main() {
......
package auth package auth
import ( import (
gossh "golang.org/x/crypto/ssh"
"github.com/gliderlabs/ssh" "github.com/gliderlabs/ssh"
"cocogo/pkg/common" "cocogo/pkg/common"
"cocogo/pkg/service" "cocogo/pkg/service"
) )
func CheckUserPassword(ctx ssh.Context, password string) bool {
return true
}
func CheckUserPublicKey(ctx ssh.Context, key ssh.PublicKey) bool { func CheckUserPublicKey(ctx ssh.Context, key ssh.PublicKey) bool {
username := ctx.User() username := ctx.User()
b := key.Marshal() b := key.Marshal()
...@@ -18,5 +24,8 @@ func CheckUserPublicKey(ctx ssh.Context, key ssh.PublicKey) bool { ...@@ -18,5 +24,8 @@ func CheckUserPublicKey(ctx ssh.Context, key ssh.PublicKey) bool {
} }
ctx.SetValue("LoginUser", authUser) ctx.SetValue("LoginUser", authUser)
return true return true
}
func CheckMFA(ctx ssh.Context, challenger gossh.KeyboardInteractiveChallenge) bool {
return true
} }
...@@ -26,6 +26,7 @@ type Config struct { ...@@ -26,6 +26,7 @@ type Config struct {
TelnetRegex string `json:"TERMINAL_TELNET_REGEX"` TelnetRegex string `json:"TERMINAL_TELNET_REGEX"`
MaxIdleTime time.Duration `json:"SECURITY_MAX_IDLE_TIME"` MaxIdleTime time.Duration `json:"SECURITY_MAX_IDLE_TIME"`
Name string `yaml:"NAME"` Name string `yaml:"NAME"`
HostKeyFile string `yaml:"HOST_KEY_FILE"`
CoreHost string `yaml:"CORE_HOST"` CoreHost string `yaml:"CORE_HOST"`
BootstrapToken string `yaml:"BOOTSTRAP_TOKEN"` BootstrapToken string `yaml:"BOOTSTRAP_TOKEN"`
BindHost string `yaml:"BIND_HOST"` BindHost string `yaml:"BIND_HOST"`
......
...@@ -40,3 +40,7 @@ func Error(args ...interface{}) { ...@@ -40,3 +40,7 @@ func Error(args ...interface{}) {
func Panic(args ...interface{}) { func Panic(args ...interface{}) {
logrus.Panic(args...) logrus.Panic(args...)
} }
func Fatal(args ...interface{}) {
logrus.Fatal(args...)
}
package record package record
import ( import (
"cocogo/pkg/auth"
"cocogo/pkg/config"
"cocogo/pkg/storage"
"compress/gzip" "compress/gzip"
"context" "context"
"encoding/json" "encoding/json"
...@@ -13,10 +10,15 @@ import ( ...@@ -13,10 +10,15 @@ import (
"path/filepath" "path/filepath"
"strings" "strings"
"time" "time"
"cocogo/pkg/config"
"cocogo/pkg/storage"
) )
var conf = config.Conf
func NewReplyRecord(sessionID string) *Reply { func NewReplyRecord(sessionID string) *Reply {
rootPath := config.GetGlobalConfig().RootPath rootPath := conf.RootPath
currentData := time.Now().UTC().Format("2006-01-02") currentData := time.Now().UTC().Format("2006-01-02")
gzFileName := sessionID + ".replay.gz" gzFileName := sessionID + ".replay.gz"
absFilePath := filepath.Join(rootPath, "data", "replays", currentData, sessionID) absFilePath := filepath.Join(rootPath, "data", "replays", currentData, sessionID)
...@@ -52,9 +54,9 @@ func (r *Reply) Record(b []byte) { ...@@ -52,9 +54,9 @@ func (r *Reply) Record(b []byte) {
} }
func (r *Reply) StartRecord() { func (r *Reply) StartRecord() {
auth.MakeSureDirExit(r.absFilePath) //auth.MakeSureDirExit(r.absFilePath)
r.WriteF, _ = os.Create(r.absFilePath) //r.WriteF, _ = os.Create(r.absFilePath)
_, _ = r.WriteF.Write([]byte("{")) //_, _ = r.WriteF.Write([]byte("{"))
} }
func (r *Reply) EndRecord(ctx context.Context) { func (r *Reply) EndRecord(ctx context.Context) {
......
package service package service
import ( import (
"fmt"
"cocogo/pkg/logger" "cocogo/pkg/logger"
"cocogo/pkg/model" "cocogo/pkg/model"
) )
...@@ -20,12 +18,12 @@ import ( ...@@ -20,12 +18,12 @@ import (
// //
//} //}
// //
func GetSystemUserAuthInfo(systemUserID string) { func GetSystemUserAssetAuthInfo(systemUserID, assetID string) (info model.SystemUserAuthInfo, err error) {
var authInfo model.SystemUserAuthInfo var authInfo model.SystemUserAuthInfo
err := client.Get("systemUserAuthInfo", nil, &authInfo) err = Client.Get("systemUserAuthInfo", nil, &authInfo)
if err != nil { if err != nil {
logger.Info("get User Assets Groups err:", err) logger.Info("get User Assets Groups err:", err)
return return
} }
fmt.Println(authInfo) return
} }
package service package service
import ( import (
"cocogo/pkg/model"
"net/http" "net/http"
"path" "path"
"path/filepath" "path/filepath"
...@@ -61,10 +60,10 @@ func (c *WrapperClient) LoadAuth() error { ...@@ -61,10 +60,10 @@ func (c *WrapperClient) LoadAuth() error {
} }
func (c *WrapperClient) CheckAuth() error { func (c *WrapperClient) CheckAuth() error {
var user model.User //var user model.User
err := c.Get("UserProfileUrl", &user) //err := c.Get("UserProfileUrl", &user)
if err != nil { //if err != nil {
return err // return err
} //}
return nil return nil
} }
...@@ -6,15 +6,15 @@ import ( ...@@ -6,15 +6,15 @@ import (
"cocogo/pkg/logger" "cocogo/pkg/logger"
) )
var client = WrapperClient{} var Client = WrapperClient{}
func init() { func init() {
err := client.LoadAuth() err := Client.LoadAuth()
if err != nil { if err != nil {
logger.Error("Load client access key error: %s", err) logger.Error("Load client access key error: %s", err)
os.Exit(10) os.Exit(10)
} }
err = client.CheckAuth() err = Client.CheckAuth()
if err != nil { if err != nil {
logger.Error("Check client auth error: %s", err) logger.Error("Check client auth error: %s", err)
os.Exit(11) os.Exit(11)
......
package service package service
import "cocogo/pkg/model"
func CheckAuth(username, password, publicKey, remoteAddr, loginType string) (user model.User, err error) {
return user, nil
}
// //
//func (s *Service) CheckAuth(username, password, publicKey, remoteAddr, loginType string) (model.User, error) { //func (s *Service) CheckAuth(username, password, publicKey, remoteAddr, loginType string) (model.User, error) {
// /* // /*
......
package sshd package handlers
const welcomeTemplate = ` import (
"text/template"
"github.com/gliderlabs/ssh"
"cocogo/pkg/logger"
)
const bannerTemplate = `
{{.UserName}} Welcome to use Jumpserver open source fortress system{{.EndLine}} {{.UserName}} Welcome to use Jumpserver open source fortress system{{.EndLine}}
{{.Tab}}1) Enter {{.ColorCode}}ID{{.ColorEnd}} directly login or enter {{.ColorCode}}part IP, Hostname, Comment{{.ColorEnd}} to search login(if unique). {{.EndLine}} {{.Tab}}1) Enter {{.ColorCode}}ID{{.ColorEnd}} directly login or enter {{.ColorCode}}part IP, Hostname, Comment{{.ColorEnd}} to search login(if unique). {{.EndLine}}
{{.Tab}}2) Enter {{.ColorCode}}/{{.ColorEnd}} + {{.ColorCode}}IP, Hostname{{.ColorEnd}} or {{.ColorCode}}Comment{{.ColorEnd}} search, such as: /ip. {{.EndLine}} {{.Tab}}2) Enter {{.ColorCode}}/{{.ColorEnd}} + {{.ColorCode}}IP, Hostname{{.ColorEnd}} or {{.ColorCode}}Comment{{.ColorEnd}} search, such as: /ip. {{.EndLine}}
...@@ -12,3 +20,30 @@ const welcomeTemplate = ` ...@@ -12,3 +20,30 @@ const welcomeTemplate = `
{{.Tab}}8) Enter {{.ColorCode}}r{{.ColorEnd}} to refresh your assets and nodes.{{.EndLine}} {{.Tab}}8) Enter {{.ColorCode}}r{{.ColorEnd}} to refresh your assets and nodes.{{.EndLine}}
{{.Tab}}0) Enter {{.ColorCode}}q{{.ColorEnd}} exit.{{.EndLine}} {{.Tab}}0) Enter {{.ColorCode}}q{{.ColorEnd}} exit.{{.EndLine}}
` `
var displayTemplate = template.Must(template.New("display").Parse(bannerTemplate))
type Banner struct {
UserName string
ColorCode string
ColorEnd string
Tab string
EndLine string
}
func (h *Banner) display(sess ssh.Session) {
e := displayTemplate.Execute(sess, h)
if e != nil {
logger.Warn("Display help info failed")
}
}
func NewBanner(userName string) *Banner {
return &Banner{
UserName: userName,
ColorCode: GreenColorCode,
ColorEnd: ColorEnd,
Tab: Tab,
EndLine: EndLine,
}
}
package sshd package handlers
const ( const (
GreenColorCode = "\033[32m" GreenColorCode = "\033[32m"
......
This diff is collapsed.
package sshd
import (
"golang.org/x/crypto/ssh"
"io/ioutil"
"os"
)
type HostKey struct {
Value string
Path string
}
func (hk *HostKey) loadHostKeyFromFile(keyPath string) (signer ssh.Signer, err error) {
_, err = os.Stat(conf.HostKeyFile)
if err != nil {
return
}
buf, err := ioutil.ReadFile(conf.HostKeyFile)
if err != nil {
return
}
return hk.loadHostKeyFromString(string(buf))
}
func (hk *HostKey) loadHostKeyFromString(value string) (signer ssh.Signer, err error) {
signer, err = ssh.ParsePrivateKey([]byte(value))
return
}
func (hk *HostKey) Gen() (signer ssh.Signer, err error) {
return
}
func (hk *HostKey) SaveToFile(signer ssh.Signer) (err error) {
return
}
func (hk *HostKey) Load() (signer ssh.Signer, err error) {
if hk.Value != "" {
signer, err = hk.loadHostKeyFromString(hk.Value)
if err == nil {
return
}
}
if hk.Path != "" {
signer, err = hk.loadHostKeyFromFile(hk.Path)
if err == nil {
return
}
}
signer, err = hk.Gen()
if err != nil {
return
}
err = hk.SaveToFile(signer)
if err != nil {
return
}
return
}
This diff is collapsed.
package sshd package sshd
import ( import (
"cocogo/pkg/auth"
"cocogo/pkg/config"
"cocogo/pkg/model"
"io"
"strconv" "strconv"
"sync"
"text/template"
"golang.org/x/crypto/ssh/terminal"
"github.com/gliderlabs/ssh" "github.com/gliderlabs/ssh"
"github.com/sirupsen/logrus"
"cocogo/pkg/auth"
"cocogo/pkg/config"
"cocogo/pkg/logger"
"cocogo/pkg/sshd/handlers"
) )
var ( var (
conf *config.Config conf = config.Conf
appService *auth.Service
serverSig ssh.Signer
displayTemplate *template.Template
log *logrus.Logger
Cached *sync.Map
) )
func Initial() {
displayTemplate = template.Must(template.New("display").Parse(welcomeTemplate))
Cached = new(sync.Map)
conf = config.GetGlobalConfig()
appService = auth.GetGlobalService()
serverSig = parsePrivateKey(conf.TermConfig.HostKey)
log = logrus.New()
if level, err := logrus.ParseLevel(conf.LogLevel); err != nil {
log.SetLevel(logrus.InfoLevel)
} else {
log.SetLevel(level)
}
}
func StartServer() { func StartServer() {
srv := ssh.Server{ hostKey := HostKey{Value: conf.HostKey, Path: conf.HostKeyFile}
Addr: conf.BindHost + ":" + strconv.Itoa(conf.SSHPort), signer, err := hostKey.Load()
PasswordHandler: appService.CheckSSHPassword, if err != nil {
PublicKeyHandler: appService.CheckSSHPublicKey, logger.Fatal("Load access key error: %s", err)
HostSigners: []ssh.Signer{serverSig},
Version: "coco-v1.4",
Handler: connectHandler,
} }
log.Fatal(srv.ListenAndServe())
}
func connectHandler(sess ssh.Session) { srv := ssh.Server{
_, _, ptyOk := sess.Pty() Addr: conf.BindHost + ":" + strconv.Itoa(conf.SSHPort),
if ptyOk { PasswordHandler: auth.CheckUserPassword,
user, ok := sess.Context().Value("LoginUser").(model.User) PublicKeyHandler: auth.CheckUserPublicKey,
if !ok { KeyboardInteractiveHandler: auth.CheckMFA,
log.Info("Get current User failed") HostSigners: []ssh.Signer{signer},
return Version: "coco-v1.4",
} Handler: handlers.SessionHandler,
userInteractive := &sshInteractive{
sess: sess,
term: terminal.NewTerminal(sess, "Opt>"),
user: user,
assetData: new(sync.Map),
helpInfo: HelpInfo{UserName: sess.User(),
ColorCode: GreenColorCode,
ColorEnd: ColorEnd,
Tab: Tab,
EndLine: EndLine}}
log.Info("accept one session")
userInteractive.displayHelpInfo()
userInteractive.StartDispatch()
} else {
_, err := io.WriteString(sess, "No PTY requested.\n")
if err != nil {
return
}
} }
logger.Fatal(srv.ListenAndServe())
} }
package sshd
import (
gossh "golang.org/x/crypto/ssh"
)
func parsePrivateKey(privateKey string) gossh.Signer {
private, err := gossh.ParsePrivateKey([]byte(privateKey))
if err != nil {
log.Error("Failed to parse private key: ", err)
}
return private
}
package storage package storage
import "cocogo/pkg/config"
type Storage interface { type Storage interface {
Upload(gZipFile, target string) Upload(gZipFile, target string)
} }
func NewStorageServer() Storage { func NewStorageServer() Storage {
conf := config.GetGlobalConfig() //conf := config.GetGlobalConfig()
//
switch conf.TermConfig.RePlayStorage["TYPE"] { //switch conf.TermConfig.RePlayStorage["TYPE"] {
case "server": //case "server":
return NewJmsStorage() // return NewJmsStorage()
} //}
return nil return nil
} }
package storage package storage
import ( //var client = service.Client
"cocogo/pkg/auth"
"path/filepath"
"strings"
)
func NewJmsStorage() Storage { func NewJmsStorage() Storage {
appService := auth.GetGlobalService() //appService := auth.GetGlobalService()
return &Server{ //return &Server{
StorageType: "jms", // StorageType: "jms",
service: appService, // service: appService,
} //}
return &Server{}
} }
type Server struct { type Server struct {
StorageType string StorageType string
service *auth.Service
} }
func (s *Server) Upload(gZipFilePath, target string) { func (s *Server) Upload(gZipFilePath, target string) {
sessionID := strings.Split(filepath.Base(gZipFilePath), ".")[0] //sessionID := strings.Split(filepath.Base(gZipFilePath), ".")[0]
_ = s.service.PushSessionReplay(gZipFilePath, sessionID) //_ = client.PushSessionReplay(gZipFilePath, sessionID)
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment