Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e74f7221b5 | ||
|
|
f4fc3a90bc | ||
|
|
df3aa6e165 | ||
|
|
986bcd7971 | ||
|
|
7f3ea431a1 | ||
|
|
dae0252857 | ||
|
|
33b8e5272c | ||
|
|
21e73757ac | ||
|
|
bcb5d3b7ef | ||
|
|
d2f3f460b2 | ||
|
|
e06fe6f5a3 | ||
|
|
fb9dabfe6b |
3
renovate.json → .github/renovate.json
vendored
3
renovate.json → .github/renovate.json
vendored
@@ -2,5 +2,6 @@
|
||||
"extends": [
|
||||
"config:base"
|
||||
],
|
||||
"groupName": "all"
|
||||
"groupName": "all",
|
||||
"gomodTidy": true
|
||||
}
|
||||
@@ -1,8 +1,10 @@
|
||||
run:
|
||||
deadline: 1m
|
||||
tests: false
|
||||
#skip-files:
|
||||
# - ".*\\.gen\\.go"
|
||||
skip-files:
|
||||
- "testing.go"
|
||||
- ".*\\.pb\\.go"
|
||||
- ".*\\.gen\\.go"
|
||||
|
||||
linters-settings:
|
||||
golint:
|
||||
@@ -18,17 +20,36 @@ linters-settings:
|
||||
linters:
|
||||
disable-all: true
|
||||
enable:
|
||||
- goconst
|
||||
- misspell
|
||||
- bodyclose
|
||||
- deadcode
|
||||
- misspell
|
||||
- structcheck
|
||||
- depguard
|
||||
- dogsled
|
||||
#- dupl
|
||||
- errcheck
|
||||
- unused
|
||||
- varcheck
|
||||
- staticcheck
|
||||
- unconvert
|
||||
#- funlen
|
||||
- gochecknoinits
|
||||
#- gocognit
|
||||
- goconst
|
||||
- gocritic
|
||||
#- gocyclo
|
||||
- gofmt
|
||||
- goimports
|
||||
- golint
|
||||
- gosimple
|
||||
- govet
|
||||
- ineffassign
|
||||
- interfacer
|
||||
#- maligned
|
||||
- misspell
|
||||
- nakedret
|
||||
- prealloc
|
||||
- scopelint
|
||||
- staticcheck
|
||||
- structcheck
|
||||
#- stylecheck
|
||||
- typecheck
|
||||
- unconvert
|
||||
- unparam
|
||||
- unused
|
||||
- varcheck
|
||||
- whitespace
|
||||
|
||||
29
AUTHORS
Normal file
29
AUTHORS
Normal file
@@ -0,0 +1,29 @@
|
||||
# This file lists all individuals having contributed content to the repository.
|
||||
# For how it is generated, see 'https://github.com/moul/rules.mk'
|
||||
|
||||
ahh <ahamidullah@gmail.com>
|
||||
Alen Masic <alenn.masic@gmail.com>
|
||||
Alexander Turner <me@alexturner.co>
|
||||
bozzo <bozzo@users.noreply.github.com>
|
||||
fossabot <badges@fossa.io>
|
||||
Jean-Louis Férey <jeanlouis.ferey@orange.com>
|
||||
Jess <jessachandler@gmail.com>
|
||||
Jonathan Lestrelin <jonathan.lestrelin@gmail.com>
|
||||
Julien Dessaux <julien.dessaux@adyxax.org>
|
||||
Manfred Touron <94029+moul@users.noreply.github.com>
|
||||
Manfred Touron <m@42.am>
|
||||
Manuel <manuel.sabban@nbs-system.com>
|
||||
Manuel Sabban <manu@sabban.eu>
|
||||
Manuel Sabban <msa@nbs-system.com>
|
||||
Mathieu Pasquet <mathieu.pasquet@alterway.fr>
|
||||
Mikael Rapp <micke.rapp@gmail.com>
|
||||
MitaliBo <mitali.bisht14@gmail.com>
|
||||
Nelly Asher <karmelylle@rambler.ru>
|
||||
NocFlame <aad@nocflame.se>
|
||||
Quentin Perez <qperez42@gmail.com>
|
||||
Renovate Bot <bot@renovateapp.com>
|
||||
Shawn Wang <shawn111@gmail.com>
|
||||
Valentin Daviot <valentin.daviot@alterway.fr>
|
||||
valentin.daviot <valentin.daviot@alterway.fr>
|
||||
welderpb <welderpb@users.noreply.github.com>
|
||||
Дмитрий Шульгачик <tech@uniplug.ru>
|
||||
8
go.mod
8
go.mod
@@ -4,14 +4,14 @@ require (
|
||||
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be
|
||||
github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect
|
||||
github.com/creack/pty v1.1.10 // indirect
|
||||
github.com/creack/pty v1.1.11 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/docker/docker v1.13.1
|
||||
github.com/dustin/go-humanize v1.0.0
|
||||
github.com/gliderlabs/ssh v0.3.0
|
||||
github.com/go-sql-driver/mysql v1.5.0 // indirect
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e // indirect
|
||||
github.com/jinzhu/gorm v1.9.12
|
||||
github.com/jinzhu/gorm v1.9.14
|
||||
github.com/kr/pty v1.1.8
|
||||
github.com/mattn/go-colorable v0.1.6 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.9 // indirect
|
||||
@@ -24,8 +24,8 @@ require (
|
||||
github.com/smartystreets/assertions v0.0.0-20190401211740-f487f9de1cd3 // indirect
|
||||
github.com/smartystreets/goconvey v1.6.4
|
||||
github.com/urfave/cli v1.22.4
|
||||
golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9
|
||||
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25 // indirect
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9
|
||||
golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980 // indirect
|
||||
gopkg.in/gormigrate.v1 v1.6.0
|
||||
moul.io/srand v1.4.0
|
||||
)
|
||||
|
||||
19
go.sum
19
go.sum
@@ -1,5 +1,7 @@
|
||||
cloud.google.com/go v0.33.1/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc=
|
||||
github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
|
||||
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
|
||||
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
|
||||
github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 h1:4daAzAu0S6Vi7/lbWECcX0j45yZReDZ56BQsrVBOEEY=
|
||||
@@ -10,8 +12,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/creack/pty v1.1.7 h1:6pwm8kMQKCmgUg0ZHTm5+/YvRK0s3THD/28+T6/kk4A=
|
||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||
github.com/creack/pty v1.1.10 h1:Xv3/hZlzZeTSMk5upBEt3iFdxWaPS3xYIm+BBySIqlY=
|
||||
github.com/creack/pty v1.1.10/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw=
|
||||
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
@@ -43,6 +45,8 @@ github.com/jinzhu/gorm v1.9.2 h1:lCvgEaqe/HVE+tjAR2mt4HbbHAZsQOv3XAZiEZV37iw=
|
||||
github.com/jinzhu/gorm v1.9.2/go.mod h1:Vla75njaFJ8clLU1W44h34PjIkijhjHIYnZxMqCdxqo=
|
||||
github.com/jinzhu/gorm v1.9.12 h1:Drgk1clyWT9t9ERbzHza6Mj/8FY/CqMyVzOiHviMo6Q=
|
||||
github.com/jinzhu/gorm v1.9.12/go.mod h1:vhTjlKSJUTWNtcbQtrMBFCxy7eXTzeCAzfL5fBZT/Qs=
|
||||
github.com/jinzhu/gorm v1.9.14 h1:Kg3ShyTPcM6nzVo148fRrcMO6MNKuqtOUwnzqMgVniM=
|
||||
github.com/jinzhu/gorm v1.9.14/go.mod h1:G3LB3wezTOWM2ITLzPxEXgSkOXAntiLHS7UdBefADcs=
|
||||
github.com/jinzhu/inflection v0.0.0-20180308033659-04140366298a h1:eeaG9XMUvRBYXJi4pg1ZKM7nxc5AfXfojeLLW7O5J3k=
|
||||
github.com/jinzhu/inflection v0.0.0-20180308033659-04140366298a/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||
@@ -70,6 +74,7 @@ github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/Qd
|
||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mattn/go-sqlite3 v1.10.0 h1:jbhqpg7tQe4SupckyijYiy0mJJ/pRyHvXf7JdWK860o=
|
||||
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus=
|
||||
github.com/mattn/go-sqlite3 v2.0.1+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U=
|
||||
github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
@@ -105,15 +110,21 @@ golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACk
|
||||
golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9 h1:vEg9joUBmeBcK9iSJftGNf3coIG4HqZElCPehJsfAYM=
|
||||
golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25 h1:OKbAoGs4fGM5cPLlVQLZGYkFC8OnOfgo6tt0Smf9XhM=
|
||||
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980 h1:OjiUf46hAmXblsZdnoSXsEUSKU8r1UEzcL5RVZ4gO9Y=
|
||||
golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
|
||||
@@ -12,7 +12,7 @@ func (a byWeight) Len() int { return len(a) }
|
||||
func (a byWeight) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
||||
func (a byWeight) Less(i, j int) bool { return a[i].Weight < a[j].Weight }
|
||||
|
||||
func checkACLs(user dbmodels.User, host dbmodels.Host) (string, error) {
|
||||
func checkACLs(user dbmodels.User, host dbmodels.Host) string {
|
||||
// shared ACLs between user and host
|
||||
aclMap := map[uint]*dbmodels.ACL{}
|
||||
for _, userGroup := range user.Groups {
|
||||
@@ -30,7 +30,7 @@ func checkACLs(user dbmodels.User, host dbmodels.Host) (string, error) {
|
||||
|
||||
// deny by default if no shared ACL
|
||||
if len(aclMap) == 0 {
|
||||
return string(dbmodels.ACLActionDeny), nil // default action
|
||||
return string(dbmodels.ACLActionDeny) // default action
|
||||
}
|
||||
|
||||
// transform map to slice and sort it
|
||||
@@ -40,5 +40,5 @@ func checkACLs(user dbmodels.User, host dbmodels.Host) (string, error) {
|
||||
}
|
||||
sort.Sort(byWeight(acls))
|
||||
|
||||
return acls[0].Action, nil
|
||||
return acls[0].Action
|
||||
}
|
||||
|
||||
@@ -43,8 +43,7 @@ func TestCheckACLs(t *testing.T) {
|
||||
db.Preload("Groups").Preload("Groups.ACLs").Find(&users)
|
||||
|
||||
// test
|
||||
action, err := checkACLs(users[0], hosts[0])
|
||||
c.So(err, ShouldBeNil)
|
||||
action := checkACLs(users[0], hosts[0])
|
||||
c.So(action, ShouldEqual, dbmodels.ACLActionAllow)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -261,14 +261,14 @@ func DBInit(db *gorm.DB) error {
|
||||
return err
|
||||
}
|
||||
|
||||
var users []dbmodels.User
|
||||
var users []*dbmodels.User
|
||||
if err := db.Preload("Roles").Where("is_admin = ?", true).Find(&users).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, user := range users {
|
||||
user.Roles = append(user.Roles, &adminRole)
|
||||
if err := tx.Save(&user).Error; err != nil {
|
||||
if err := tx.Save(user).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -358,7 +358,7 @@ func DBInit(db *gorm.DB) error {
|
||||
}, {
|
||||
ID: "24",
|
||||
Migrate: func(tx *gorm.DB) error {
|
||||
var userKeys []dbmodels.UserKey
|
||||
var userKeys []*dbmodels.UserKey
|
||||
if err := db.Find(&userKeys).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -369,7 +369,7 @@ func DBInit(db *gorm.DB) error {
|
||||
return err
|
||||
}
|
||||
userKey.AuthorizedKey = string(gossh.MarshalAuthorizedKey(key))
|
||||
if err := db.Model(&userKey).Updates(&userKey).Error; err != nil {
|
||||
if err := db.Model(userKey).Updates(userKey).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -422,14 +422,14 @@ func DBInit(db *gorm.DB) error {
|
||||
}, {
|
||||
ID: "27",
|
||||
Migrate: func(tx *gorm.DB) error {
|
||||
var sessions []dbmodels.Session
|
||||
var sessions []*dbmodels.Session
|
||||
if err := db.Find(&sessions).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, session := range sessions {
|
||||
if session.StoppedAt != nil && session.StoppedAt.IsZero() {
|
||||
if err := db.Model(&session).Updates(map[string]interface{}{"stopped_at": nil}).Error; err != nil {
|
||||
if err := db.Model(session).Updates(map[string]interface{}{"stopped_at": nil}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package bastion // import "moul.io/sshportal/pkg/bastion"
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
@@ -20,7 +19,7 @@ type sessionConfig struct {
|
||||
ClientConfig *gossh.ClientConfig
|
||||
}
|
||||
|
||||
func multiChannelHandler(srv *ssh.Server, conn *gossh.ServerConn, newChan gossh.NewChannel, ctx ssh.Context, configs []sessionConfig, sessionID uint) error {
|
||||
func multiChannelHandler(conn *gossh.ServerConn, newChan gossh.NewChannel, ctx ssh.Context, configs []sessionConfig, sessionID uint) error {
|
||||
var lastClient *gossh.Client
|
||||
switch newChan.ChannelType() {
|
||||
case "session":
|
||||
@@ -124,6 +123,7 @@ func pipe(lreqs, rreqs <-chan *gossh.Request, lch, rch gossh.Channel, logsLocati
|
||||
}()
|
||||
|
||||
errch := make(chan error, 1)
|
||||
quit := make(chan string, 1)
|
||||
channeltype := newChan.ChannelType()
|
||||
|
||||
filename := strings.Join([]string{logsLocation, "/", user, "-", username, "-", channeltype, "-", fmt.Sprint(sessionID), "-", time.Now().Format(time.RFC3339)}, "") // get user
|
||||
@@ -139,15 +139,15 @@ func pipe(lreqs, rreqs <-chan *gossh.Request, lch, rch gossh.Channel, logsLocati
|
||||
log.Printf("Session %v is recorded in %v", channeltype, filename)
|
||||
if channeltype == "session" {
|
||||
wrappedlch := logchannel.New(lch, f)
|
||||
go func() {
|
||||
go func(quit chan string) {
|
||||
_, _ = io.Copy(wrappedlch, rch)
|
||||
errch <- errors.New("lch closed the connection")
|
||||
}()
|
||||
quit <- "rch"
|
||||
}(quit)
|
||||
|
||||
go func() {
|
||||
go func(quit chan string) {
|
||||
_, _ = io.Copy(rch, lch)
|
||||
errch <- errors.New("rch closed the connection")
|
||||
}()
|
||||
quit <- "lch"
|
||||
}(quit)
|
||||
}
|
||||
if channeltype == "direct-tcpip" {
|
||||
d := logTunnelForwardData{}
|
||||
@@ -156,23 +156,19 @@ func pipe(lreqs, rreqs <-chan *gossh.Request, lch, rch gossh.Channel, logsLocati
|
||||
}
|
||||
wrappedlch := newLogTunnel(lch, f, d.SourceHost)
|
||||
wrappedrch := newLogTunnel(rch, f, d.DestinationHost)
|
||||
go func() {
|
||||
go func(quit chan string) {
|
||||
_, _ = io.Copy(wrappedlch, rch)
|
||||
errch <- errors.New("lch closed the connection")
|
||||
}()
|
||||
quit <- "rch"
|
||||
}(quit)
|
||||
|
||||
go func() {
|
||||
go func(quit chan string) {
|
||||
_, _ = io.Copy(wrappedrch, lch)
|
||||
errch <- errors.New("rch closed the connection")
|
||||
}()
|
||||
quit <- "lch"
|
||||
}(quit)
|
||||
}
|
||||
|
||||
for {
|
||||
select {
|
||||
case req := <-lreqs: // forward ssh requests from local to remote
|
||||
if req == nil {
|
||||
return nil
|
||||
}
|
||||
go func(quit chan string) {
|
||||
for req := range lreqs {
|
||||
b, err := rch.SendRequest(req.Type, req.WantReply, req.Payload)
|
||||
if req.Type == "exec" {
|
||||
wrappedlch := logchannel.New(lch, f)
|
||||
@@ -183,24 +179,58 @@ func pipe(lreqs, rreqs <-chan *gossh.Request, lch, rch gossh.Channel, logsLocati
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
errch <- err
|
||||
}
|
||||
if err2 := req.Reply(b, nil); err2 != nil {
|
||||
return err2
|
||||
}
|
||||
case req := <-rreqs: // forward ssh requests from remote to local
|
||||
if req == nil {
|
||||
return nil
|
||||
errch <- err2
|
||||
}
|
||||
}
|
||||
quit <- "lreqs"
|
||||
}(quit)
|
||||
|
||||
go func(quit chan string) {
|
||||
for req := range rreqs {
|
||||
b, err := lch.SendRequest(req.Type, req.WantReply, req.Payload)
|
||||
if err != nil {
|
||||
return err
|
||||
errch <- err
|
||||
}
|
||||
if err2 := req.Reply(b, nil); err2 != nil {
|
||||
return err2
|
||||
errch <- err2
|
||||
}
|
||||
}
|
||||
quit <- "rreqs"
|
||||
}(quit)
|
||||
|
||||
lchEOF, rchEOF, lchClosed, rchClosed := false, false, false, false
|
||||
for {
|
||||
select {
|
||||
case err := <-errch:
|
||||
return err
|
||||
case q := <-quit:
|
||||
switch q {
|
||||
case "lch":
|
||||
lchEOF = true
|
||||
_ = rch.CloseWrite()
|
||||
case "rch":
|
||||
rchEOF = true
|
||||
_ = lch.CloseWrite()
|
||||
case "lreqs":
|
||||
lchClosed = true
|
||||
case "rreqs":
|
||||
rchClosed = true
|
||||
}
|
||||
|
||||
if lchEOF && lchClosed && !rchClosed {
|
||||
rch.Close()
|
||||
}
|
||||
|
||||
if rchEOF && rchClosed && !lchClosed {
|
||||
lch.Close()
|
||||
}
|
||||
|
||||
if lchEOF && rchEOF && lchClosed && rchClosed {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,6 +67,8 @@ GLOBAL OPTIONS:
|
||||
app.Writer = s
|
||||
app.HideVersion = true
|
||||
|
||||
dbmodels.InitValidator()
|
||||
|
||||
var (
|
||||
myself = &actx.user
|
||||
db = actx.db
|
||||
@@ -173,10 +175,8 @@ GLOBAL OPTIONS:
|
||||
return err
|
||||
}
|
||||
acls = append(acls, &acl)
|
||||
} else {
|
||||
if err := query.Find(&acls).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
} else if err := query.Find(&acls).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if c.Bool("quiet") {
|
||||
for _, acl := range acls {
|
||||
@@ -250,14 +250,14 @@ GLOBAL OPTIONS:
|
||||
return err
|
||||
}
|
||||
|
||||
var acls []dbmodels.ACL
|
||||
var acls []*dbmodels.ACL
|
||||
if err := dbmodels.ACLsByIdentifiers(db, c.Args()).Find(&acls).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tx := db.Begin()
|
||||
for _, acl := range acls {
|
||||
model := tx.Model(&acl)
|
||||
model := tx.Model(acl)
|
||||
update := dbmodels.ACL{
|
||||
Action: c.String("action"),
|
||||
HostPattern: c.String("pattern"),
|
||||
@@ -477,6 +477,7 @@ GLOBAL OPTIONS:
|
||||
}
|
||||
}
|
||||
for _, host := range config.Hosts {
|
||||
host := host
|
||||
crypto.HostDecrypt(actx.aesKey, host)
|
||||
if !c.Bool("decrypt") {
|
||||
if err := crypto.HostEncrypt(actx.aesKey, host); err != nil {
|
||||
@@ -489,30 +490,35 @@ GLOBAL OPTIONS:
|
||||
}
|
||||
}
|
||||
for _, user := range config.Users {
|
||||
user := user
|
||||
if err := tx.FirstOrCreate(&user).Error; err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
}
|
||||
for _, acl := range config.ACLs {
|
||||
acl := acl
|
||||
if err := tx.FirstOrCreate(&acl).Error; err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
}
|
||||
for _, hostGroup := range config.HostGroups {
|
||||
hostGroup := hostGroup
|
||||
if err := tx.FirstOrCreate(&hostGroup).Error; err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
}
|
||||
for _, userGroup := range config.UserGroups {
|
||||
userGroup := userGroup
|
||||
if err := tx.FirstOrCreate(&userGroup).Error; err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
}
|
||||
for _, sshKey := range config.SSHKeys {
|
||||
sshKey := sshKey
|
||||
crypto.SSHKeyDecrypt(actx.aesKey, sshKey)
|
||||
if !c.Bool("decrypt") {
|
||||
if err := crypto.SSHKeyEncrypt(actx.aesKey, sshKey); err != nil {
|
||||
@@ -525,24 +531,28 @@ GLOBAL OPTIONS:
|
||||
}
|
||||
}
|
||||
for _, userKey := range config.UserKeys {
|
||||
userKey := userKey
|
||||
if err := tx.FirstOrCreate(&userKey).Error; err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
}
|
||||
for _, setting := range config.Settings {
|
||||
setting := setting
|
||||
if err := tx.FirstOrCreate(&setting).Error; err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
}
|
||||
for _, session := range config.Sessions {
|
||||
session := session
|
||||
if err := tx.FirstOrCreate(&session).Error; err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
}
|
||||
for _, event := range config.Events {
|
||||
event := event
|
||||
if err := tx.FirstOrCreate(&event).Error; err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
@@ -612,10 +622,8 @@ GLOBAL OPTIONS:
|
||||
return err
|
||||
}
|
||||
events = append(events, event)
|
||||
} else {
|
||||
if err := query.Find(&events).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
} else if err := query.Find(&events).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if c.Bool("quiet") {
|
||||
@@ -799,10 +807,8 @@ GLOBAL OPTIONS:
|
||||
return err
|
||||
}
|
||||
hosts = append(hosts, &host)
|
||||
} else {
|
||||
if err := query.Find(&hosts).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
} else if err := query.Find(&hosts).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if c.Bool("quiet") {
|
||||
@@ -820,7 +826,7 @@ GLOBAL OPTIONS:
|
||||
authKey := ""
|
||||
if host.SSHKeyID > 0 {
|
||||
var key dbmodels.SSHKey
|
||||
db.Model(&host).Related(&key)
|
||||
db.Model(host).Related(&key)
|
||||
authKey = key.Name
|
||||
}
|
||||
groupNames := []string{}
|
||||
@@ -830,7 +836,7 @@ GLOBAL OPTIONS:
|
||||
var hop string
|
||||
if host.HopID != 0 {
|
||||
var hopHost dbmodels.Host
|
||||
db.Model(&host).Related(&hopHost, "HopID")
|
||||
db.Model(host).Related(&hopHost, "HopID")
|
||||
hop = hopHost.Name
|
||||
} else {
|
||||
hop = ""
|
||||
@@ -900,6 +906,7 @@ GLOBAL OPTIONS:
|
||||
|
||||
tx := db.Begin()
|
||||
for _, host := range hosts {
|
||||
host := host
|
||||
model := tx.Model(&host)
|
||||
// simple fields
|
||||
for _, fieldname := range []string{"name", "comment"} {
|
||||
@@ -1063,10 +1070,8 @@ GLOBAL OPTIONS:
|
||||
return err
|
||||
}
|
||||
hostGroups = append(hostGroups, &hostGroup)
|
||||
} else {
|
||||
if err := query.Find(&hostGroups).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
} else if err := query.Find(&hostGroups).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if c.Bool("quiet") {
|
||||
@@ -1127,7 +1132,7 @@ GLOBAL OPTIONS:
|
||||
return err
|
||||
}
|
||||
|
||||
var hostgroups []dbmodels.HostGroup
|
||||
var hostgroups []*dbmodels.HostGroup
|
||||
if err := dbmodels.HostGroupsByIdentifiers(db, c.Args()).Find(&hostgroups).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -1138,7 +1143,7 @@ GLOBAL OPTIONS:
|
||||
|
||||
tx := db.Begin()
|
||||
for _, hostgroup := range hostgroups {
|
||||
model := tx.Model(&hostgroup)
|
||||
model := tx.Model(hostgroup)
|
||||
// simple fields
|
||||
for _, fieldname := range []string{"name", "comment"} {
|
||||
if c.String(fieldname) != "" {
|
||||
@@ -1342,10 +1347,8 @@ GLOBAL OPTIONS:
|
||||
return err
|
||||
}
|
||||
sshKeys = append(sshKeys, &sshKey)
|
||||
} else {
|
||||
if err := query.Find(&sshKeys).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
} else if err := query.Find(&sshKeys).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if c.Bool("quiet") {
|
||||
for _, sshKey := range sshKeys {
|
||||
@@ -1584,10 +1587,8 @@ GLOBAL OPTIONS:
|
||||
return err
|
||||
}
|
||||
users = append(users, &user)
|
||||
} else {
|
||||
if err := query.Find(&users).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
} else if err := query.Find(&users).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if c.Bool("quiet") {
|
||||
for _, user := range users {
|
||||
@@ -1661,7 +1662,7 @@ GLOBAL OPTIONS:
|
||||
}
|
||||
|
||||
// FIXME: check if unset-admin + user == myself
|
||||
var users []dbmodels.User
|
||||
var users []*dbmodels.User
|
||||
if err := dbmodels.UsersByIdentifiers(db, c.Args()).Find(&users).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -1676,7 +1677,7 @@ GLOBAL OPTIONS:
|
||||
|
||||
tx := db.Begin()
|
||||
for _, user := range users {
|
||||
model := tx.Model(&user)
|
||||
model := tx.Model(user)
|
||||
// simple fields
|
||||
for _, fieldname := range []string{"name", "email", "comment"} {
|
||||
if c.String(fieldname) != "" {
|
||||
@@ -1814,10 +1815,8 @@ GLOBAL OPTIONS:
|
||||
return err
|
||||
}
|
||||
userGroups = append(userGroups, &userGroup)
|
||||
} else {
|
||||
if err := query.Find(&userGroups).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
} else if err := query.Find(&userGroups).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if c.Bool("quiet") {
|
||||
for _, userGroup := range userGroups {
|
||||
@@ -1877,7 +1876,7 @@ GLOBAL OPTIONS:
|
||||
return err
|
||||
}
|
||||
|
||||
var usergroups []dbmodels.UserGroup
|
||||
var usergroups []*dbmodels.UserGroup
|
||||
if err := dbmodels.UserGroupsByIdentifiers(db, c.Args()).Find(&usergroups).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -1888,7 +1887,7 @@ GLOBAL OPTIONS:
|
||||
|
||||
tx := db.Begin()
|
||||
for _, usergroup := range usergroups {
|
||||
model := tx.Model(&usergroup)
|
||||
model := tx.Model(usergroup)
|
||||
// simple fields
|
||||
for _, fieldname := range []string{"name", "comment"} {
|
||||
if c.String(fieldname) != "" {
|
||||
@@ -2001,10 +2000,8 @@ GLOBAL OPTIONS:
|
||||
return err
|
||||
}
|
||||
userKeys = append(userKeys, &userKey)
|
||||
} else {
|
||||
if err := query.Find(&userKeys).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
} else if err := query.Find(&userKeys).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if c.Bool("quiet") {
|
||||
for _, userKey := range userKeys {
|
||||
@@ -2112,7 +2109,6 @@ GLOBAL OPTIONS:
|
||||
|
||||
factor := 1
|
||||
for len(sessions) >= limit*factor {
|
||||
|
||||
var additionnalSessions []*dbmodels.Session
|
||||
|
||||
offset = limit * factor
|
||||
|
||||
@@ -149,7 +149,7 @@ func ChannelHandler(srv *ssh.Server, conn *gossh.ServerConn, newChan gossh.NewCh
|
||||
return
|
||||
}
|
||||
go func() {
|
||||
err = multiChannelHandler(srv, conn, newChan, ctx, sessionConfigs, sess.ID)
|
||||
err = multiChannelHandler(conn, newChan, ctx, sessionConfigs, sess.ID)
|
||||
if err != nil {
|
||||
log.Printf("Error: %v", err)
|
||||
}
|
||||
@@ -160,8 +160,7 @@ func ChannelHandler(srv *ssh.Server, conn *gossh.ServerConn, newChan gossh.NewCh
|
||||
ErrMsg: fmt.Sprintf("%v", err),
|
||||
StoppedAt: &now,
|
||||
}
|
||||
switch sessUpdate.ErrMsg {
|
||||
case "lch closed the connection", "rch closed the connection":
|
||||
if err == nil {
|
||||
sessUpdate.ErrMsg = ""
|
||||
}
|
||||
actx.db.Model(&sess).Updates(&sessUpdate)
|
||||
@@ -205,11 +204,8 @@ func bastionClientConfig(ctx ssh.Context, host *dbmodels.Host) (*gossh.ClientCon
|
||||
if err = actx.db.Preload("Groups").Preload("Groups.ACLs").Where("id = ?", host.ID).First(&tmpHost).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
action, err2 := checkACLs(tmpUser, tmpHost)
|
||||
if err2 != nil {
|
||||
return nil, err2
|
||||
}
|
||||
|
||||
action := checkACLs(tmpUser, tmpHost)
|
||||
switch action {
|
||||
case string(dbmodels.ACLActionAllow):
|
||||
// do nothing
|
||||
|
||||
@@ -5,12 +5,10 @@ import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net/url"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/asaskevich/govalidator"
|
||||
"github.com/jinzhu/gorm"
|
||||
gossh "golang.org/x/crypto/ssh"
|
||||
)
|
||||
@@ -166,18 +164,6 @@ const (
|
||||
BastionSchemeTelnet BastionScheme = "telnet"
|
||||
)
|
||||
|
||||
func init() {
|
||||
unixUserRegexp := regexp.MustCompile("[a-z_][a-z0-9_-]*")
|
||||
|
||||
govalidator.CustomTypeTagMap.Set("unix_user", govalidator.CustomTypeValidator(func(i interface{}, context interface{}) bool {
|
||||
name, ok := i.(string)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return unixUserRegexp.MatchString(name)
|
||||
}))
|
||||
}
|
||||
|
||||
// Host helpers
|
||||
|
||||
func (host *Host) DialAddr() string {
|
||||
|
||||
19
pkg/dbmodels/validator.go
Normal file
19
pkg/dbmodels/validator.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package dbmodels
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
|
||||
"github.com/asaskevich/govalidator"
|
||||
)
|
||||
|
||||
func InitValidator() {
|
||||
unixUserRegexp := regexp.MustCompile("[a-z_][a-z0-9_-]*")
|
||||
|
||||
govalidator.CustomTypeTagMap.Set("unix_user", govalidator.CustomTypeValidator(func(i interface{}, context interface{}) bool {
|
||||
name, ok := i.(string)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return unixUserRegexp.MatchString(name)
|
||||
}))
|
||||
}
|
||||
14
testserver_unsupported.go
Normal file
14
testserver_unsupported.go
Normal file
@@ -0,0 +1,14 @@
|
||||
// +build windows
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
// testServer is an hidden handler used for integration tests
|
||||
func testServer(c *cli.Context) error {
|
||||
return fmt.Errorf("not available on windows")
|
||||
}
|
||||
Reference in New Issue
Block a user