Compare commits
11 Commits
v1.8.0
...
dev/moul/s
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a125e25b04 | ||
|
|
07e6344c82 | ||
|
|
d016e674a8 | ||
|
|
64c8e01c33 | ||
|
|
acce797e55 | ||
|
|
175fc8d68b | ||
|
|
41eeb364f8 | ||
|
|
a22f8f0b7b | ||
|
|
bd1c3609a7 | ||
|
|
c5e75df64f | ||
|
|
227b64aaac |
@@ -1,5 +1,9 @@
|
||||
# Changelog
|
||||
|
||||
## master (unreleased)
|
||||
|
||||
* No entry
|
||||
|
||||
## v1.8.0 (2018-04-02)
|
||||
|
||||
* The default created user now has the same username as the user starting sshportal (was hardcoded "admin")
|
||||
|
||||
@@ -3,6 +3,7 @@ package main
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
@@ -13,6 +14,7 @@ type configServe struct {
|
||||
logsLocation string
|
||||
bindAddr string
|
||||
debug, demo bool
|
||||
idleTimeout time.Duration
|
||||
}
|
||||
|
||||
func parseServeConfig(c *cli.Context) (*configServe, error) {
|
||||
@@ -24,6 +26,7 @@ func parseServeConfig(c *cli.Context) (*configServe, error) {
|
||||
debug: c.Bool("debug"),
|
||||
demo: c.Bool("demo"),
|
||||
logsLocation: c.String("logs-location"),
|
||||
idleTimeout: c.Duration("idle-timeout"),
|
||||
}
|
||||
switch len(ret.aesKey) {
|
||||
case 0, 16, 24, 32:
|
||||
|
||||
@@ -64,12 +64,16 @@ ssh sshportal -l admin config backup --indent --ignore-events > backup-2
|
||||
diff backup-1.clean backup-2.clean
|
||||
)
|
||||
|
||||
# bastion
|
||||
ssh sshportal -l admin host create --name=testserver toto@testserver:2222
|
||||
out="$(ssh sshportal -l testserver echo hello | head -n 1)"
|
||||
test "$out" = '{"User":"toto","Environ":null,"Command":["echo","hello"]}'
|
||||
if [ "$CIRCLECI" = "true" ]; then
|
||||
echo "Strage behavior with cross-container communication on CircleCI, skipping some tests..."
|
||||
else
|
||||
# bastion
|
||||
ssh sshportal -l admin host create --name=testserver toto@testserver:2222
|
||||
out="$(ssh sshportal -l testserver echo hello | head -n 1)"
|
||||
test "$out" = '{"User":"toto","Environ":null,"Command":["echo","hello"]}'
|
||||
|
||||
out="$(TEST_A=1 TEST_B=2 TEST_C=3 TEST_D=4 TEST_E=5 TEST_F=6 TEST_G=7 TEST_H=8 TEST_I=9 ssh sshportal -l testserver echo hello | head -n 1)"
|
||||
test "$out" = '{"User":"toto","Environ":["TEST_A=1","TEST_B=2","TEST_C=3","TEST_D=4","TEST_E=5","TEST_F=6","TEST_G=7","TEST_H=8","TEST_I=9"],"Command":["echo","hello"]}'
|
||||
out="$(TEST_A=1 TEST_B=2 TEST_C=3 TEST_D=4 TEST_E=5 TEST_F=6 TEST_G=7 TEST_H=8 TEST_I=9 ssh sshportal -l testserver echo hello | head -n 1)"
|
||||
test "$out" = '{"User":"toto","Environ":["TEST_A=1","TEST_B=2","TEST_C=3","TEST_D=4","TEST_E=5","TEST_F=6","TEST_G=7","TEST_H=8","TEST_I=9"],"Command":["echo","hello"]}'
|
||||
fi
|
||||
|
||||
# TODO: test more cases (forwards, scp, sftp, interactive, pty, stdin, exit code, ...)
|
||||
|
||||
12
hidden_unsupported.go
Normal file
12
hidden_unsupported.go
Normal file
@@ -0,0 +1,12 @@
|
||||
// +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 supported on this architecture") }
|
||||
16
main.go
16
main.go
@@ -3,6 +3,7 @@ package main
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"math"
|
||||
"math/rand"
|
||||
"net"
|
||||
"os"
|
||||
@@ -18,7 +19,7 @@ import (
|
||||
|
||||
var (
|
||||
// Version should be updated by hand at each release
|
||||
Version = "1.8.0"
|
||||
Version = "1.8.0+dev"
|
||||
// GitTag will be overwritten automatically by the build system
|
||||
GitTag string
|
||||
// GitSha will be overwritten automatically by the build system
|
||||
@@ -79,6 +80,11 @@ func main() {
|
||||
Value: "./log",
|
||||
Usage: "Store user session files",
|
||||
},
|
||||
cli.DurationFlag{
|
||||
Name: "idle-timeout",
|
||||
Value: 0,
|
||||
Usage: "Duration before an inactive connection is timed out (0 to disable)",
|
||||
},
|
||||
},
|
||||
}, {
|
||||
Name: "healthcheck",
|
||||
@@ -144,6 +150,12 @@ func server(c *configServe) (err error) {
|
||||
Version: fmt.Sprintf("sshportal-%s", Version),
|
||||
ChannelHandler: channelHandler,
|
||||
}
|
||||
if c.idleTimeout != 0 {
|
||||
srv.IdleTimeout = c.idleTimeout
|
||||
// gliderlabs/ssh requires MaxTimeout to be non-zero if we want to use IdleTimeout.
|
||||
// So, set it to the max value, because we don't want a max timeout.
|
||||
srv.MaxTimeout = math.MaxInt64
|
||||
}
|
||||
|
||||
for _, opt := range []ssh.Option{
|
||||
// custom PublicKeyAuth handler
|
||||
@@ -157,6 +169,6 @@ func server(c *configServe) (err error) {
|
||||
}
|
||||
}
|
||||
|
||||
log.Printf("info: SSH Server accepting connections on %s", c.bindAddr)
|
||||
log.Printf("info: SSH Server accepting connections on %s, idle-timout=%v", c.bindAddr, c.idleTimeout)
|
||||
return srv.Serve(ln)
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@ import (
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -124,8 +126,8 @@ func pipe(lreqs, rreqs <-chan *gossh.Request, lch, rch gossh.Channel, logsLocati
|
||||
|
||||
errch := make(chan error, 1)
|
||||
channeltype := newChan.ChannelType()
|
||||
|
||||
file_name := strings.Join([]string{logsLocation, "/", user, "-", channeltype, "-", time.Now().Format(time.RFC3339)}, "") // get user
|
||||
fileNameUnix := strings.Join([]string{logsLocation, "/", user, "-", channeltype, "-", strconv.FormatInt(time.Now().UnixNano(), 10)}, "") // get user
|
||||
file_name := filepath.FromSlash(fileNameUnix)
|
||||
f, err := os.OpenFile(file_name, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0640)
|
||||
defer f.Close()
|
||||
|
||||
|
||||
82
shell.go
82
shell.go
@@ -1095,6 +1095,47 @@ GLOBAL OPTIONS:
|
||||
|
||||
return HostGroupsByIdentifiers(db, c.Args()).Delete(&HostGroup{}).Error
|
||||
},
|
||||
}, {
|
||||
Name: "update",
|
||||
Usage: "Updates a host group",
|
||||
ArgsUsage: "HOSTGROUP...",
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{Name: "name", Usage: "Assigns a new name to the host group"},
|
||||
cli.StringFlag{Name: "comment", Usage: "Adds a comment"},
|
||||
},
|
||||
Action: func(c *cli.Context) error {
|
||||
if c.NArg() < 1 {
|
||||
return cli.ShowSubcommandHelp(c)
|
||||
}
|
||||
|
||||
if err := myself.CheckRoles([]string{"admin"}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var hostgroups []HostGroup
|
||||
if err := HostGroupsByIdentifiers(db, c.Args()).Find(&hostgroups).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(hostgroups) > 1 && c.String("name") != "" {
|
||||
return fmt.Errorf("cannot set --name when editing multiple hostgroups at once")
|
||||
}
|
||||
|
||||
tx := db.Begin()
|
||||
for _, hostgroup := range hostgroups {
|
||||
model := tx.Model(&hostgroup)
|
||||
// simple fields
|
||||
for _, fieldname := range []string{"name", "comment"} {
|
||||
if c.String(fieldname) != "" {
|
||||
if err := model.Update(fieldname, c.String(fieldname)).Error; err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return tx.Commit().Error
|
||||
},
|
||||
},
|
||||
},
|
||||
}, {
|
||||
@@ -1804,6 +1845,47 @@ GLOBAL OPTIONS:
|
||||
|
||||
return UserGroupsByIdentifiers(db, c.Args()).Delete(&UserGroup{}).Error
|
||||
},
|
||||
}, {
|
||||
Name: "update",
|
||||
Usage: "Updates a user group",
|
||||
ArgsUsage: "USERGROUP...",
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{Name: "name", Usage: "Assigns a new name to the user group"},
|
||||
cli.StringFlag{Name: "comment", Usage: "Adds a comment"},
|
||||
},
|
||||
Action: func(c *cli.Context) error {
|
||||
if c.NArg() < 1 {
|
||||
return cli.ShowSubcommandHelp(c)
|
||||
}
|
||||
|
||||
if err := myself.CheckRoles([]string{"admin"}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var usergroups []UserGroup
|
||||
if err := UserGroupsByIdentifiers(db, c.Args()).Find(&usergroups).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(usergroups) > 1 && c.String("name") != "" {
|
||||
return fmt.Errorf("cannot set --name when editing multiple usergroups at once")
|
||||
}
|
||||
|
||||
tx := db.Begin()
|
||||
for _, usergroup := range usergroups {
|
||||
model := tx.Model(&usergroup)
|
||||
// simple fields
|
||||
for _, fieldname := range []string{"name", "comment"} {
|
||||
if c.String(fieldname) != "" {
|
||||
if err := model.Update(fieldname, c.String(fieldname)).Error; err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return tx.Commit().Error
|
||||
},
|
||||
},
|
||||
},
|
||||
}, {
|
||||
|
||||
Reference in New Issue
Block a user