Commit 93d1b3f1 authored by ibuler's avatar ibuler

Merge branch 'master' of github.com:LeeEirc/cocogo

parents 1184db28 334493e0
package auth package auth
import ( import (
"cocogo/pkg/cctx"
"cocogo/pkg/i18n" "cocogo/pkg/i18n"
"strings" "strings"
...@@ -29,12 +30,28 @@ func checkAuth(ctx ssh.Context, password, publicKey string) (res ssh.AuthResult) ...@@ -29,12 +30,28 @@ func checkAuth(ctx ssh.Context, password, publicKey string) (res ssh.AuthResult)
} }
if err != nil { if err != nil {
action = "Failed" action = "Failed"
} else if resp.Seed != "" && resp.Token == "" { } else if resp.Seed != "" && resp.Token == "" {
ctx.SetValue(contentKeyMFASeed, resp.Seed) ctx.SetValue(contentKeyMFASeed, resp.Seed)
res = ssh.AuthPartiallySuccessful res = ssh.AuthPartiallySuccessful
} else { } else {
res = ssh.AuthSuccessful res = ssh.AuthSuccessful
} }
if resp != nil {
switch resp.User.IsMFA {
case 0:
res = ssh.AuthSuccessful
case 1:
res = ssh.AuthPartiallySuccessful
case 2:
res = ssh.AuthPartiallySuccessful
default:
}
ctx.SetValue(cctx.ContextKeyUser, resp.User)
ctx.SetValue(cctx.ContextKeySeed, resp.Seed)
ctx.SetValue(cctx.ContextKeyToken, resp.Token)
}
logger.Infof("%s %s for %s from %s", action, authMethod, username, remoteAddr) logger.Infof("%s %s for %s from %s", action, authMethod, username, remoteAddr)
return res return res
} }
...@@ -51,6 +68,7 @@ func CheckUserPublicKey(ctx ssh.Context, key ssh.PublicKey) ssh.AuthResult { ...@@ -51,6 +68,7 @@ func CheckUserPublicKey(ctx ssh.Context, key ssh.PublicKey) ssh.AuthResult {
} }
func CheckMFA(ctx ssh.Context, challenger gossh.KeyboardInteractiveChallenge) ssh.AuthResult { func CheckMFA(ctx ssh.Context, challenger gossh.KeyboardInteractiveChallenge) ssh.AuthResult {
username := ctx.User() username := ctx.User()
answers, err := challenger(username, mfaInstruction, []string{mfaQuestion}, []bool{true}) answers, err := challenger(username, mfaInstruction, []string{mfaQuestion}, []bool{true})
if err != nil { if err != nil {
...@@ -66,6 +84,7 @@ func CheckMFA(ctx ssh.Context, challenger gossh.KeyboardInteractiveChallenge) ss ...@@ -66,6 +84,7 @@ func CheckMFA(ctx ssh.Context, challenger gossh.KeyboardInteractiveChallenge) ss
return ssh.AuthFailed return ssh.AuthFailed
} }
resp, err := service.CheckUserOTP(seed, mfaCode) resp, err := service.CheckUserOTP(seed, mfaCode)
if err != nil { if err != nil {
logger.Error("Mfa Auth failed: ", err) logger.Error("Mfa Auth failed: ", err)
return ssh.AuthFailed return ssh.AuthFailed
......
...@@ -19,6 +19,8 @@ var ( ...@@ -19,6 +19,8 @@ var (
ContextKeySSHSession = &contextKey{"sshSession"} ContextKeySSHSession = &contextKey{"sshSession"}
ContextKeyLocalAddr = &contextKey{"localAddr"} ContextKeyLocalAddr = &contextKey{"localAddr"}
ContextKeySSHCtx = &contextKey{"sshCtx"} ContextKeySSHCtx = &contextKey{"sshCtx"}
ContextKeySeed = &contextKey{"seed"}
ContextKeyToken = &contextKey{"token"}
) )
type Context interface { type Context interface {
......
...@@ -29,6 +29,7 @@ func SessionHandler(sess ssh.Session) { ...@@ -29,6 +29,7 @@ func SessionHandler(sess ssh.Session) {
_, _, ptyOk := sess.Pty() _, _, ptyOk := sess.Pty()
if ptyOk { if ptyOk {
ctx, cancel := cctx.NewContext(sess) ctx, cancel := cctx.NewContext(sess)
fmt.Println(ctx.User())
handler := &InteractiveHandler{ handler := &InteractiveHandler{
sess: sess, sess: sess,
user: ctx.User(), user: ctx.User(),
...@@ -88,6 +89,7 @@ func (i *InteractiveHandler) watchWinSizeChange(winCh <-chan ssh.Window, done <- ...@@ -88,6 +89,7 @@ func (i *InteractiveHandler) watchWinSizeChange(winCh <-chan ssh.Window, done <-
func (i *InteractiveHandler) Dispatch(ctx cctx.Context) { func (i *InteractiveHandler) Dispatch(ctx cctx.Context) {
i.preDispatch() i.preDispatch()
fmt.Println(i.user)
_, winCh, _ := i.sess.Pty() _, winCh, _ := i.sess.Pty()
for { for {
doneChan := make(chan struct{}) doneChan := make(chan struct{})
...@@ -323,8 +325,8 @@ func (i *InteractiveHandler) searchNodeAssets(num int) (assets []model.Asset) { ...@@ -323,8 +325,8 @@ func (i *InteractiveHandler) searchNodeAssets(num int) (assets []model.Asset) {
} }
func (i *InteractiveHandler) Proxy(ctx context.Context) { func (i *InteractiveHandler) Proxy(ctx context.Context) {
i.assetSelect = &model.Asset{Hostname: "centos", Port: 22, Ip: "192.168.244.185"} i.assetSelect = &model.Asset{Hostname: "centos", Port: 32768, Ip: "127.0.0.1"}
i.systemUserSelect = &model.SystemUser{Name: "web", UserName: "web", Password: "redhat"} i.systemUserSelect = &model.SystemUser{Name: "web", UserName: "root", Password: "screencast"}
p := proxy.ProxyServer{ p := proxy.ProxyServer{
Session: i.sess, Session: i.sess,
User: i.user, User: i.user,
......
...@@ -18,6 +18,12 @@ package model ...@@ -18,6 +18,12 @@ package model
'date_expired': '2089-03-21 18:18:24 +0800'} 'date_expired': '2089-03-21 18:18:24 +0800'}
*/ */
type AuthResponse struct {
Token string `json:"token"`
Seed string `json:"seed"`
User *User `json:"user"`
}
type User struct { type User struct {
Id string `json:"id"` Id string `json:"id"`
Name string `json:"name"` Name string `json:"name"`
...@@ -27,6 +33,7 @@ type User struct { ...@@ -27,6 +33,7 @@ type User struct {
Role string `json:"role"` Role string `json:"role"`
IsValid bool `json:"is_valid"` IsValid bool `json:"is_valid"`
IsActive bool `json:"is_active"` IsActive bool `json:"is_active"`
IsMFA int `json:"otp_level"`
} }
type TokenUser struct { type TokenUser struct {
......
...@@ -3,6 +3,7 @@ package proxy ...@@ -3,6 +3,7 @@ package proxy
import ( import (
"fmt" "fmt"
"io" "io"
"strconv"
"strings" "strings"
"time" "time"
...@@ -13,7 +14,6 @@ import ( ...@@ -13,7 +14,6 @@ import (
"cocogo/pkg/logger" "cocogo/pkg/logger"
"cocogo/pkg/model" "cocogo/pkg/model"
"cocogo/pkg/service" "cocogo/pkg/service"
"strconv"
) )
type ProxyServer struct { type ProxyServer struct {
......
...@@ -15,7 +15,7 @@ func GetUserAssets(userId, cachePolicy string) (assets model.AssetList) { ...@@ -15,7 +15,7 @@ func GetUserAssets(userId, cachePolicy string) (assets model.AssetList) {
Url := fmt.Sprintf(UserAssetsURL, userId) Url := fmt.Sprintf(UserAssetsURL, userId)
err := authClient.Get(Url, &assets, payload) err := authClient.Get(Url, &assets, payload)
if err != nil { if err != nil {
logger.Error(err) logger.Error("GetUserAssets---err")
} }
return return
} }
...@@ -28,7 +28,7 @@ func GetUserNodes(userId, cachePolicy string) (nodes model.NodeList) { ...@@ -28,7 +28,7 @@ func GetUserNodes(userId, cachePolicy string) (nodes model.NodeList) {
Url := fmt.Sprintf(UserNodesAssetsURL, userId) Url := fmt.Sprintf(UserNodesAssetsURL, userId)
err := authClient.Get(Url, &nodes, payload) err := authClient.Get(Url, &nodes, payload)
if err != nil { if err != nil {
logger.Error(err) logger.Error("GetUserNodes err")
} }
return return
} }
......
...@@ -7,6 +7,8 @@ const ( ...@@ -7,6 +7,8 @@ const (
UserDetailURL = "/api/users/v1/users/%s/" // 获取用户信息 UserDetailURL = "/api/users/v1/users/%s/" // 获取用户信息
UserAuthOTPURL = "/api/users/v1/otp/auth/" // 验证OTP UserAuthOTPURL = "/api/users/v1/otp/auth/" // 验证OTP
AuthMFAURL = "/api/authentication/v1/otp/auth/" // MFA 验证用户信息
SystemUserAssetAuthURL = "/api/assets/v1/system-user/%s/asset/%s/auth-info/" // 该系统用户对某资产的授权 SystemUserAssetAuthURL = "/api/assets/v1/system-user/%s/asset/%s/auth-info/" // 该系统用户对某资产的授权
SystemUserAuthInfoURL = "/api/assets/v1/system-user/%s/auth-info/" // 该系统用户的授权 SystemUserAuthInfoURL = "/api/assets/v1/system-user/%s/auth-info/" // 该系统用户的授权
SystemUserCmdFilterRules = "/api/assets/v1/system-user/%s/cmd-filter-rules/" // 过滤规则url SystemUserCmdFilterRules = "/api/assets/v1/system-user/%s/cmd-filter-rules/" // 过滤规则url
......
...@@ -2,6 +2,7 @@ package service ...@@ -2,6 +2,7 @@ package service
import ( import (
"fmt" "fmt"
"github.com/pkg/errors" "github.com/pkg/errors"
"cocogo/pkg/logger" "cocogo/pkg/logger"
...@@ -22,14 +23,40 @@ func Authenticate(username, password, publicKey, remoteAddr, loginType string) ( ...@@ -22,14 +23,40 @@ func Authenticate(username, password, publicKey, remoteAddr, loginType string) (
"remote_addr": remoteAddr, "remote_addr": remoteAddr,
"login_type": loginType, "login_type": loginType,
} }
err = client.Post(UserAuthURL, data, &resp) Url := client.ParseUrl(UserAuthURL, nil)
err = client.Post(Url, data, &resp)
if err != nil { if err != nil {
logger.Error(err) logger.Error(err)
return
} }
return return
} }
func AuthenticateMFA(seed, code, loginType string) (resp *model.AuthResponse, err error) {
/*
data = {
'seed': seed,
'otp_code': otp_code,
'login_type': login_type,
}
*/
data := map[string]string{
"seed": seed,
"otp_code": code,
"login_type": loginType,
}
Url := client.ParseUrl(AuthMFAURL, nil)
err = client.Post(Url, data, resp)
if err != nil {
logger.Error(err)
}
return
}
func GetUserProfile(userId string) (user *model.User) { func GetUserProfile(userId string) (user *model.User) {
Url := fmt.Sprintf(UserDetailURL, userId) Url := fmt.Sprintf(UserDetailURL, userId)
err := authClient.Get(Url, user) err := authClient.Get(Url, user)
......
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