Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
K
koko
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ops
koko
Commits
93d1b3f1
Commit
93d1b3f1
authored
May 09, 2019
by
ibuler
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' of github.com:LeeEirc/cocogo
parents
1184db28
334493e0
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
66 additions
and
7 deletions
+66
-7
server.go
pkg/auth/server.go
+19
-0
context.go
pkg/cctx/context.go
+2
-0
session.go
pkg/handler/session.go
+4
-2
users.go
pkg/model/users.go
+7
-0
proxy.go
pkg/proxy/proxy.go
+1
-1
perms.go
pkg/service/perms.go
+2
-2
urls.go
pkg/service/urls.go
+2
-0
users.go
pkg/service/users.go
+29
-2
No files found.
pkg/auth/server.go
View file @
93d1b3f1
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
...
...
pkg/cctx/context.go
View file @
93d1b3f1
...
@@ -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
{
...
...
pkg/handler/session.go
View file @
93d1b3f1
...
@@ -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
:
"redha
t"
}
i
.
systemUserSelect
=
&
model
.
SystemUser
{
Name
:
"web"
,
UserName
:
"
root"
,
Password
:
"screencas
t"
}
p
:=
proxy
.
ProxyServer
{
p
:=
proxy
.
ProxyServer
{
Session
:
i
.
sess
,
Session
:
i
.
sess
,
User
:
i
.
user
,
User
:
i
.
user
,
...
...
pkg/model/users.go
View file @
93d1b3f1
...
@@ -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
{
...
...
pkg/proxy/proxy.go
View file @
93d1b3f1
...
@@ -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
{
...
...
pkg/service/perms.go
View file @
93d1b3f1
...
@@ -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
}
}
...
...
pkg/service/urls.go
View file @
93d1b3f1
...
@@ -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
...
...
pkg/service/users.go
View file @
93d1b3f1
...
@@ -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
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment