Compare commits
61 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e455d50db9 | ||
|
|
be3f215e24 | ||
|
|
c290253546 | ||
|
|
5b4332072c | ||
|
|
762736d622 | ||
|
|
bbbc484fe8 | ||
|
|
e1602364c8 | ||
|
|
2540d1e861 | ||
|
|
177a198420 | ||
|
|
51612aab13 | ||
|
|
e20af1dde5 | ||
|
|
6caa1f1657 | ||
|
|
e0f76d15ec | ||
|
|
bcc150727f | ||
|
|
9062417d13 | ||
|
|
baeade4043 | ||
|
|
b9552e98b5 | ||
|
|
715ccde829 | ||
|
|
f5dc1bd1b9 | ||
|
|
c79c50aeb6 | ||
|
|
df3542c6ee | ||
|
|
e40f5307a3 | ||
|
|
6e6045306b | ||
|
|
874467b1e6 | ||
|
|
5c1c559a9a | ||
|
|
6872c727ef | ||
|
|
cae996d041 | ||
|
|
a23b77282c | ||
|
|
24814c4152 | ||
|
|
07359988d0 | ||
|
|
db6eb63297 | ||
|
|
5fdb31b97d | ||
|
|
bce6b1998b | ||
|
|
f7fa60da97 | ||
|
|
d2cd6b64a3 | ||
|
|
1ef0cc8725 | ||
|
|
d894005c3f | ||
|
|
af7206d114 | ||
|
|
1f9d962cd6 | ||
|
|
460041c6e3 | ||
|
|
7068565ab1 | ||
|
|
74bd885c1d | ||
|
|
9317f206d1 | ||
|
|
6c3f803dc6 | ||
|
|
9c3d29eb83 | ||
|
|
e339a73931 | ||
|
|
0dcab1b380 | ||
|
|
032f802348 | ||
|
|
7fd9be9058 | ||
|
|
83b54aeeff | ||
|
|
2323d6fd1e | ||
|
|
4c947ce391 | ||
|
|
44559f0547 | ||
|
|
8234119cd4 | ||
|
|
7a75c13ac4 | ||
|
|
4b10131790 | ||
|
|
a29c6e8338 | ||
|
|
198e0717b5 | ||
|
|
d8fa2f6925 | ||
|
|
16c8c0092e | ||
|
|
b0dfff2d90 |
BIN
.assets/bastion.jpg
Normal file
|
After Width: | Height: | Size: 249 KiB |
|
Before Width: | Height: | Size: 8.5 KiB After Width: | Height: | Size: 7.1 KiB |
BIN
.assets/demo.gif
|
Before Width: | Height: | Size: 179 KiB After Width: | Height: | Size: 171 KiB |
|
Before Width: | Height: | Size: 104 KiB After Width: | Height: | Size: 79 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 9.2 KiB After Width: | Height: | Size: 8.0 KiB |
|
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 34 KiB |
@@ -1,7 +1,7 @@
|
||||
defaults: &defaults
|
||||
working_directory: /go/src/moul.io/sshportal
|
||||
docker:
|
||||
- image: circleci/golang:1.14.6
|
||||
- image: circleci/golang:1.16.2
|
||||
environment:
|
||||
GO111MODULE: "on"
|
||||
|
||||
@@ -27,6 +27,7 @@ jobs:
|
||||
curl -L https://github.com/docker/compose/releases/download/1.11.4/docker-compose-`uname -s`-`uname -m` > ~/docker-compose
|
||||
- setup_remote_docker:
|
||||
docker_layer_caching: true
|
||||
version: 18.09.3 # https://github.com/golang/go/issues/40893
|
||||
- *install_retry
|
||||
- run: /tmp/retry -m 3 docker build -t moul/sshportal .
|
||||
- run: /tmp/retry -m 3 make integration
|
||||
|
||||
20
.github/dependabot.yml
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: docker
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: daily
|
||||
time: "04:00"
|
||||
open-pull-requests-limit: 10
|
||||
- package-ecosystem: github-actions
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: daily
|
||||
time: "04:00"
|
||||
open-pull-requests-limit: 10
|
||||
- package-ecosystem: gomod
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: daily
|
||||
time: "04:00"
|
||||
open-pull-requests-limit: 10
|
||||
14
.github/workflows/ci.yml
vendored
@@ -20,7 +20,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: lint
|
||||
uses: golangci/golangci-lint-action@v0.1.7
|
||||
uses: golangci/golangci-lint-action@v2.5.1
|
||||
with:
|
||||
version: v1.28
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -30,8 +30,7 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
golang:
|
||||
#- 1.13
|
||||
- 1.14
|
||||
- 1.15.0
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Install Go
|
||||
@@ -47,14 +46,14 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
golang:
|
||||
- 1.14
|
||||
- 1.15.0
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: ${{ matrix.golang }}
|
||||
- uses: actions/cache@v1
|
||||
- uses: actions/cache@v2.1.3
|
||||
with:
|
||||
path: ~/go/pkg/mod
|
||||
key: ${{ runner.os }}-go-${{ matrix.golang }}-${{ hashFiles('**/go.sum') }}
|
||||
@@ -68,17 +67,16 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
golang:
|
||||
- 1.11
|
||||
- 1.12
|
||||
- 1.13
|
||||
- 1.14
|
||||
- 1.15.0
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: ${{ matrix.golang }}
|
||||
- uses: actions/cache@v1
|
||||
- uses: actions/cache@v2.1.3
|
||||
with:
|
||||
path: ~/go/pkg/mod
|
||||
key: ${{ runner.os }}-go-${{ matrix.golang }}-${{ hashFiles('**/go.sum') }}
|
||||
|
||||
4
AUTHORS
generated
@@ -5,12 +5,15 @@ ahh <ahamidullah@gmail.com>
|
||||
Alen Masic <alenn.masic@gmail.com>
|
||||
Alexander Turner <me@alexturner.co>
|
||||
bozzo <bozzo@users.noreply.github.com>
|
||||
dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
|
||||
fossabot <badges@fossa.io>
|
||||
ImgBotApp <ImgBotHelp@gmail.com>
|
||||
Jean-Louis Férey <jeanlouis.ferey@orange.com>
|
||||
jerard@alfa-safety.fr <jrrdev@users.noreply.github.com>
|
||||
Jess <jessachandler@gmail.com>
|
||||
Jonathan Lestrelin <jonathan.lestrelin@gmail.com>
|
||||
Julien Dessaux <julien.dessaux@adyxax.org>
|
||||
Konstantin Bakaras <k.bakaras@voskhod.ru>
|
||||
Manfred Touron <94029+moul@users.noreply.github.com>
|
||||
Manfred Touron <m@42.am>
|
||||
Manuel <manuel.sabban@nbs-system.com>
|
||||
@@ -24,6 +27,7 @@ Nelly Asher <karmelylle@rambler.ru>
|
||||
NocFlame <aad@nocflame.se>
|
||||
Quentin Perez <qperez42@gmail.com>
|
||||
Renovate Bot <bot@renovateapp.com>
|
||||
Sergey Yashchuk <sergey.yashchuk@coins.ph>
|
||||
Shawn Wang <shawn111@gmail.com>
|
||||
Valentin Daviot <valentin.daviot@alterway.fr>
|
||||
valentin.daviot <valentin.daviot@alterway.fr>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# build
|
||||
FROM golang:1.14.6 as builder
|
||||
FROM golang:1.16.2 as builder
|
||||
ENV GO111MODULE=on
|
||||
WORKDIR /go/src/moul.io/sshportal
|
||||
COPY go.mod go.sum ./
|
||||
|
||||
2
LICENSE
@@ -186,7 +186,7 @@
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright 2017 Manfred Touron <m@42.am>
|
||||
Copyright 2017-2021 Manfred Touron <m@42.am>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
|
||||
Jump host/Jump server without the jump, a.k.a Transparent SSH bastion
|
||||
|
||||
<img src="https://raw.githubusercontent.com/moul/sshportal/master/.assets/bastion.jpg" width="50%">
|
||||
|
||||
Features include: independence of users and hosts, convenient user invite system, connecting to servers that don't support SSH keys, various levels of access, and many more. Easy to install, run and configure.
|
||||
|
||||

|
||||
|
||||
127
depaware.txt
Normal file
@@ -0,0 +1,127 @@
|
||||
moul.io/sshportal dependencies: (generated by github.com/tailscale/depaware)
|
||||
|
||||
github.com/anmitsu/go-shlex from github.com/gliderlabs/ssh+
|
||||
github.com/asaskevich/govalidator from moul.io/sshportal/pkg/bastion+
|
||||
github.com/cpuguy83/go-md2man/v2/md2man from github.com/urfave/cli
|
||||
LD 💣 github.com/creack/pty from github.com/kr/pty
|
||||
github.com/docker/docker/pkg/namesgenerator from moul.io/sshportal/pkg/bastion
|
||||
github.com/docker/docker/pkg/random from github.com/docker/docker/pkg/namesgenerator
|
||||
github.com/dustin/go-humanize from moul.io/sshportal/pkg/bastion
|
||||
github.com/gliderlabs/ssh from moul.io/sshportal+
|
||||
github.com/go-sql-driver/mysql from github.com/jinzhu/gorm/dialects/mysql+
|
||||
github.com/jinzhu/gorm from gopkg.in/gormigrate.v1+
|
||||
github.com/jinzhu/gorm/dialects/mysql from moul.io/sshportal
|
||||
github.com/jinzhu/gorm/dialects/postgres from moul.io/sshportal
|
||||
github.com/jinzhu/gorm/dialects/sqlite from moul.io/sshportal
|
||||
github.com/jinzhu/inflection from github.com/jinzhu/gorm
|
||||
LD github.com/kr/pty from moul.io/sshportal
|
||||
github.com/lib/pq from github.com/jinzhu/gorm/dialects/postgres
|
||||
github.com/lib/pq/hstore from github.com/jinzhu/gorm/dialects/postgres
|
||||
github.com/lib/pq/oid from github.com/lib/pq
|
||||
github.com/lib/pq/scram from github.com/lib/pq
|
||||
💣 github.com/mattn/go-colorable from github.com/mgutz/ansi
|
||||
💣 github.com/mattn/go-isatty from github.com/mattn/go-colorable
|
||||
github.com/mattn/go-runewidth from github.com/olekukonko/tablewriter
|
||||
💣 github.com/mattn/go-sqlite3 from github.com/jinzhu/gorm/dialects/sqlite
|
||||
github.com/mgutz/ansi from moul.io/sshportal/pkg/bastion
|
||||
github.com/olekukonko/tablewriter from moul.io/sshportal/pkg/bastion
|
||||
github.com/pkg/errors from moul.io/sshportal/pkg/bastion
|
||||
github.com/reiver/go-oi from github.com/reiver/go-telnet+
|
||||
github.com/reiver/go-telnet from moul.io/sshportal/pkg/bastion
|
||||
github.com/russross/blackfriday/v2 from github.com/cpuguy83/go-md2man/v2/md2man
|
||||
github.com/sabban/bastion/pkg/logchannel from moul.io/sshportal/pkg/bastion
|
||||
github.com/shurcooL/sanitized_anchor_name from github.com/russross/blackfriday/v2
|
||||
github.com/urfave/cli from moul.io/sshportal+
|
||||
gopkg.in/gormigrate.v1 from moul.io/sshportal/pkg/bastion
|
||||
moul.io/srand from moul.io/sshportal
|
||||
moul.io/sshportal/pkg/bastion from moul.io/sshportal
|
||||
moul.io/sshportal/pkg/crypto from moul.io/sshportal/pkg/bastion
|
||||
moul.io/sshportal/pkg/dbmodels from moul.io/sshportal/pkg/bastion+
|
||||
golang.org/x/crypto/blowfish from golang.org/x/crypto/ssh/internal/bcrypt_pbkdf
|
||||
golang.org/x/crypto/chacha20 from golang.org/x/crypto/chacha20poly1305+
|
||||
golang.org/x/crypto/chacha20poly1305 from crypto/tls
|
||||
golang.org/x/crypto/cryptobyte from crypto/ecdsa+
|
||||
golang.org/x/crypto/cryptobyte/asn1 from crypto/ecdsa+
|
||||
golang.org/x/crypto/curve25519 from crypto/tls+
|
||||
golang.org/x/crypto/ed25519 from golang.org/x/crypto/ssh
|
||||
golang.org/x/crypto/hkdf from crypto/tls
|
||||
golang.org/x/crypto/poly1305 from golang.org/x/crypto/chacha20poly1305+
|
||||
golang.org/x/crypto/ssh from github.com/gliderlabs/ssh+
|
||||
golang.org/x/crypto/ssh/terminal from moul.io/sshportal/pkg/bastion
|
||||
golang.org/x/net/dns/dnsmessage from net
|
||||
D golang.org/x/net/route from net
|
||||
golang.org/x/sys/cpu from golang.org/x/crypto/chacha20poly1305
|
||||
LD golang.org/x/sys/unix from github.com/mattn/go-isatty+
|
||||
W golang.org/x/sys/windows from golang.org/x/crypto/ssh/terminal
|
||||
bufio from crypto/rand+
|
||||
bytes from bufio+
|
||||
container/list from crypto/tls
|
||||
context from crypto/tls+
|
||||
crypto from crypto/ecdsa+
|
||||
crypto/aes from crypto/ecdsa+
|
||||
crypto/cipher from crypto/aes+
|
||||
crypto/des from crypto/tls+
|
||||
crypto/dsa from crypto/x509+
|
||||
crypto/ecdsa from crypto/tls+
|
||||
crypto/ed25519 from crypto/tls+
|
||||
crypto/elliptic from crypto/ecdsa+
|
||||
crypto/hmac from crypto/tls+
|
||||
crypto/md5 from crypto/tls+
|
||||
crypto/rand from crypto/ed25519+
|
||||
crypto/rc4 from crypto/tls+
|
||||
crypto/rsa from crypto/tls+
|
||||
crypto/sha1 from crypto/tls+
|
||||
crypto/sha256 from crypto/tls+
|
||||
crypto/sha512 from crypto/ecdsa+
|
||||
crypto/subtle from crypto/aes+
|
||||
crypto/tls from github.com/go-sql-driver/mysql+
|
||||
crypto/x509 from crypto/tls+
|
||||
crypto/x509/pkix from crypto/x509
|
||||
database/sql from github.com/go-sql-driver/mysql+
|
||||
database/sql/driver from database/sql+
|
||||
encoding from encoding/json
|
||||
encoding/asn1 from crypto/x509+
|
||||
encoding/base64 from encoding/json+
|
||||
encoding/binary from crypto/aes+
|
||||
encoding/csv from github.com/olekukonko/tablewriter
|
||||
encoding/hex from crypto/x509+
|
||||
encoding/json from github.com/asaskevich/govalidator+
|
||||
encoding/pem from crypto/tls+
|
||||
errors from bufio+
|
||||
flag from github.com/urfave/cli
|
||||
fmt from crypto/tls+
|
||||
go/ast from github.com/jinzhu/gorm
|
||||
go/scanner from go/ast
|
||||
go/token from go/ast+
|
||||
hash from crypto+
|
||||
html from github.com/asaskevich/govalidator+
|
||||
io from bufio+
|
||||
io/ioutil from crypto/tls+
|
||||
log from github.com/gliderlabs/ssh+
|
||||
math from crypto/rsa+
|
||||
math/big from crypto/dsa+
|
||||
math/bits from crypto/md5+
|
||||
math/rand from github.com/docker/docker/pkg/random+
|
||||
net from crypto/tls+
|
||||
net/url from crypto/x509+
|
||||
os from crypto/rand+
|
||||
LD os/exec from github.com/creack/pty+
|
||||
os/user from github.com/lib/pq+
|
||||
path from github.com/asaskevich/govalidator+
|
||||
path/filepath from crypto/x509+
|
||||
reflect from crypto/x509+
|
||||
regexp from github.com/asaskevich/govalidator+
|
||||
regexp/syntax from regexp
|
||||
sort from database/sql+
|
||||
strconv from crypto+
|
||||
strings from bufio+
|
||||
sync from context+
|
||||
sync/atomic from context+
|
||||
syscall from crypto/rand+
|
||||
text/tabwriter from github.com/urfave/cli
|
||||
text/template from github.com/urfave/cli
|
||||
text/template/parse from text/template
|
||||
time from context+
|
||||
unicode from bytes+
|
||||
unicode/utf16 from encoding/asn1+
|
||||
unicode/utf8 from bufio+
|
||||
21
go.mod
generated
@@ -2,33 +2,34 @@ module moul.io/sshportal
|
||||
|
||||
require (
|
||||
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be
|
||||
github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535
|
||||
github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0 // 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/gliderlabs/ssh v0.3.2
|
||||
github.com/go-sql-driver/mysql v1.5.0
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e // indirect
|
||||
github.com/jinzhu/gorm v1.9.15
|
||||
github.com/jinzhu/gorm v1.9.16
|
||||
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
|
||||
github.com/lib/pq v1.8.0 // indirect
|
||||
github.com/mattn/go-colorable v0.1.8 // indirect
|
||||
github.com/mattn/go-sqlite3 v2.0.3+incompatible // indirect
|
||||
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d
|
||||
github.com/olekukonko/tablewriter v0.0.4
|
||||
github.com/olekukonko/tablewriter v0.0.5
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/reiver/go-oi v1.0.0
|
||||
github.com/reiver/go-telnet v0.0.0-20180421082511-9ff0b2ab096e
|
||||
github.com/sabban/bastion v0.0.0-20180110125408-b9d3c9b1f4d3
|
||||
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-20200709230013-948cd5f35899
|
||||
golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980 // indirect
|
||||
github.com/stretchr/testify v1.4.0 // indirect
|
||||
github.com/urfave/cli v1.22.5
|
||||
golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f // indirect
|
||||
gopkg.in/gormigrate.v1 v1.6.0
|
||||
moul.io/srand v1.4.0
|
||||
moul.io/srand v1.6.1
|
||||
)
|
||||
|
||||
go 1.14
|
||||
|
||||
43
go.sum
generated
@@ -4,8 +4,8 @@ github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBK
|
||||
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=
|
||||
github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg=
|
||||
github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef h1:46PFijGLmAjMPwCCCo7Jf0W6f9slllCkkv7vyc1yOSg=
|
||||
github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
@@ -24,8 +24,8 @@ github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 h1:Yzb9+7DPaBjB8zlTR87/ElzFsnQfuHnVUVqpZZIcV5Y=
|
||||
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0=
|
||||
github.com/gliderlabs/ssh v0.3.0 h1:7GcKy4erEljCE/QeQ2jTVpu+3f3zkpZOxOJjFYkMqYU=
|
||||
github.com/gliderlabs/ssh v0.3.0/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
|
||||
github.com/gliderlabs/ssh v0.3.2 h1:gcfd1Aj/9RQxvygu4l3sak711f/5+VOwBw9C/7+N4EI=
|
||||
github.com/gliderlabs/ssh v0.3.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
|
||||
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
|
||||
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
@@ -38,8 +38,8 @@ github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORR
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e h1:JKmoR8x90Iww1ks85zJ1lfDGgIiMDuIptTOhJq+zKyg=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/jinzhu/gorm v1.9.2/go.mod h1:Vla75njaFJ8clLU1W44h34PjIkijhjHIYnZxMqCdxqo=
|
||||
github.com/jinzhu/gorm v1.9.15 h1:OdR1qFvtXktlxk73XFYMiYn9ywzTwytqe4QkuMRqc38=
|
||||
github.com/jinzhu/gorm v1.9.15/go.mod h1:G3LB3wezTOWM2ITLzPxEXgSkOXAntiLHS7UdBefADcs=
|
||||
github.com/jinzhu/gorm v1.9.16 h1:+IyIjPEABKRpsu/F8OvDPy9fyQlgsg2luMV2ZIH5i5o=
|
||||
github.com/jinzhu/gorm v1.9.16/go.mod h1:G3LB3wezTOWM2ITLzPxEXgSkOXAntiLHS7UdBefADcs=
|
||||
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=
|
||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||
@@ -55,11 +55,12 @@ github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
|
||||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.1.1 h1:sJZmqHoEaY7f+NPP8pgLB/WxulyR3fewgCM2qaSlBb4=
|
||||
github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/mattn/go-colorable v0.1.6 h1:6Su7aK7lXmJ/U79bYtBjLNaha4Fs1Rg9plHpcH+vvnE=
|
||||
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/lib/pq v1.8.0 h1:9xohqzkUwzR4Ga4ivdTcawVS89YSDVxXMa3xJX3cGzg=
|
||||
github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8=
|
||||
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
|
||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
@@ -68,8 +69,8 @@ github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJK
|
||||
github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI=
|
||||
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
|
||||
github.com/olekukonko/tablewriter v0.0.4 h1:vHD/YYe1Wolo78koG299f7V/VAS08c6IpCLn+Ejf/w8=
|
||||
github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA=
|
||||
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
|
||||
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
@@ -92,14 +93,16 @@ github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/urfave/cli v1.22.4 h1:u7tSpNPPswAFymm8IehJhy4uJMlUuU/GmqSkvJ1InXA=
|
||||
github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/urfave/cli v1.22.5 h1:lNq9sAHXK2qfdI8W+GRItjCEkI+2oR4d+MEHy1CKXoU=
|
||||
github.com/urfave/cli v1.22.5/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
golang.org/x/crypto v0.0.0-20181112202954-3d3f9f413869/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899 h1:DZhuSZLsGlFL4CmhA8BcRA0mnthyA/nZ00AqCUo7vHg=
|
||||
golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9 h1:umElSU9WZirRdgu2yFHY0ayQkEnKiOC1TtM3fWXFnoU=
|
||||
golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9/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=
|
||||
@@ -111,14 +114,16 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
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-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/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/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=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/gormigrate.v1 v1.6.0 h1:XpYM6RHQPmzwY7Uyu+t+xxMXc86JYFJn4nEc9HzQjsI=
|
||||
gopkg.in/gormigrate.v1 v1.6.0/go.mod h1:Lf00lQrHqfSYWiTtPcyQabsDdM6ejZaMgV0OU6JMSlw=
|
||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
moul.io/srand v1.4.0 h1:r5ZMiWDN0ni0lTV7KzJR/jx0K7GivJYW5WaXmufgeik=
|
||||
moul.io/srand v1.4.0/go.mod h1:P2uaZB+GFstFNo8sEj6/U8FRV1n25kD0LLckFpJ+qvc=
|
||||
moul.io/srand v1.6.1 h1:SJ335F+54ivLdlH7wH52Rtyv0Ffos6DpsF5wu3ZVMXU=
|
||||
moul.io/srand v1.6.1/go.mod h1:P2uaZB+GFstFNo8sEj6/U8FRV1n25kD0LLckFpJ+qvc=
|
||||
|
||||
2
main.go
@@ -22,7 +22,7 @@ var (
|
||||
)
|
||||
|
||||
func main() {
|
||||
rand.Seed(srand.Secure())
|
||||
rand.Seed(srand.MustSecure())
|
||||
|
||||
app := cli.NewApp()
|
||||
app.Name = path.Base(os.Args[0])
|
||||
|
||||
@@ -537,7 +537,7 @@ func DBInit(db *gorm.DB) error {
|
||||
return err
|
||||
}
|
||||
if count == 0 {
|
||||
key, err := crypto.NewSSHKey("rsa", 2048)
|
||||
key, err := crypto.NewSSHKey("ed25519", 1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -644,7 +644,7 @@ func DBInit(db *gorm.DB) error {
|
||||
return err
|
||||
}
|
||||
if count == 0 {
|
||||
key, err := crypto.NewSSHKey("rsa", 2048)
|
||||
key, err := crypto.NewSSHKey("ed25519", 1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -1276,8 +1276,8 @@ GLOBAL OPTIONS:
|
||||
Description: "$> key create\n $> key create --name=mykey",
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{Name: "name", Usage: "Assigns a name to the key"},
|
||||
cli.StringFlag{Name: "type", Value: "rsa"},
|
||||
cli.UintFlag{Name: "length", Value: 2048},
|
||||
cli.StringFlag{Name: "type", Value: "ed25519"},
|
||||
cli.UintFlag{Name: "length", Value: 0},
|
||||
cli.StringFlag{Name: "comment", Usage: "Adds a comment"},
|
||||
},
|
||||
Action: func(c *cli.Context) error {
|
||||
@@ -1290,7 +1290,24 @@ GLOBAL OPTIONS:
|
||||
name = c.String("name")
|
||||
}
|
||||
|
||||
key, err := crypto.NewSSHKey(c.String("type"), c.Uint("length"))
|
||||
length := c.Uint("length")
|
||||
if length == 0 {
|
||||
switch c.String("type") {
|
||||
case "rsa":
|
||||
// same default as ssh-keygen
|
||||
length = 3072
|
||||
case "ecdsa":
|
||||
// same default as ssh-keygen
|
||||
length = 256
|
||||
case "ed25519":
|
||||
// irrelevant for ed25519
|
||||
// set it to 1 to enforce consistency
|
||||
// and because 0 is invalid
|
||||
length = 1
|
||||
}
|
||||
}
|
||||
|
||||
key, err := crypto.NewSSHKey(c.String("type"), length)
|
||||
if actx.aesKey != "" {
|
||||
if err2 := crypto.SSHKeyEncrypt(actx.aesKey, key); err2 != nil {
|
||||
return err2
|
||||
@@ -1719,6 +1736,8 @@ GLOBAL OPTIONS:
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{Name: "name, n", Usage: "Renames the user"},
|
||||
cli.StringFlag{Name: "email, e", Usage: "Updates the email"},
|
||||
cli.StringFlag{Name: "invite_token, i", Usage: "Updates the invite token"},
|
||||
cli.BoolFlag{Name: "remove_invite, R", Usage: "Remove invite token"},
|
||||
cli.StringSliceFlag{Name: "assign-role, r", Usage: "Assign the user to new `USERROLES`"},
|
||||
cli.StringSliceFlag{Name: "unassign-role", Usage: "Unassign the user from `USERROLES`"},
|
||||
cli.StringSliceFlag{Name: "assign-group, g", Usage: "Assign the user to new `USERGROUPS`"},
|
||||
@@ -1751,7 +1770,7 @@ GLOBAL OPTIONS:
|
||||
for _, user := range users {
|
||||
model := tx.Model(user)
|
||||
// simple fields
|
||||
for _, fieldname := range []string{"name", "email", "comment"} {
|
||||
for _, fieldname := range []string{"name", "email", "comment", "invite_token"} {
|
||||
if c.String(fieldname) != "" {
|
||||
if err := model.Update(fieldname, c.String(fieldname)).Error; err != nil {
|
||||
tx.Rollback()
|
||||
@@ -1759,6 +1778,13 @@ GLOBAL OPTIONS:
|
||||
}
|
||||
}
|
||||
}
|
||||
// invite remove
|
||||
if c.Bool("remove_invite") {
|
||||
if err := model.Update("invite_token", "").Error; err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// associations
|
||||
var appendGroups []dbmodels.UserGroup
|
||||
|
||||
@@ -4,6 +4,9 @@ import (
|
||||
"bytes"
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"crypto/ecdsa"
|
||||
"crypto/ed25519"
|
||||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
@@ -25,35 +28,108 @@ func NewSSHKey(keyType string, length uint) (*dbmodels.SSHKey, error) {
|
||||
}
|
||||
|
||||
// generate the private key
|
||||
if keyType != "rsa" {
|
||||
return nil, fmt.Errorf("key type not supported: %q", key.Type)
|
||||
var err error
|
||||
var pemKey *pem.Block
|
||||
var publicKey gossh.PublicKey
|
||||
switch keyType {
|
||||
case "rsa":
|
||||
pemKey, publicKey, err = NewRSAKey(length)
|
||||
case "ecdsa":
|
||||
pemKey, publicKey, err = NewECDSAKey(length)
|
||||
case "ed25519":
|
||||
pemKey, publicKey, err = NewEd25519Key()
|
||||
default:
|
||||
return nil, fmt.Errorf("key type not supported: %q, supported types are: rsa, ecdsa, ed25519", key.Type)
|
||||
}
|
||||
privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// convert priv key to x509 format
|
||||
var pemKey = &pem.Block{
|
||||
Type: "RSA PRIVATE KEY",
|
||||
Bytes: x509.MarshalPKCS1PrivateKey(privateKey),
|
||||
}
|
||||
buf := bytes.NewBufferString("")
|
||||
if err = pem.Encode(buf, pemKey); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
key.PrivKey = buf.String()
|
||||
|
||||
// generte authorized-key formatted pubkey output
|
||||
pub, err := gossh.NewPublicKey(&privateKey.PublicKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
key.PubKey = strings.TrimSpace(string(gossh.MarshalAuthorizedKey(pub)))
|
||||
// generate authorized-key formatted pubkey output
|
||||
key.PubKey = strings.TrimSpace(string(gossh.MarshalAuthorizedKey(publicKey)))
|
||||
|
||||
return &key, nil
|
||||
}
|
||||
|
||||
func NewRSAKey(length uint) (*pem.Block, gossh.PublicKey, error) {
|
||||
if length < 1024 || length > 16384 {
|
||||
return nil, nil, fmt.Errorf("key length not supported: %d, supported values are between 1024 and 16384", length)
|
||||
}
|
||||
privateKey, err := rsa.GenerateKey(rand.Reader, int(length))
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
// convert priv key to x509 format
|
||||
pemKey := &pem.Block{
|
||||
Type: "RSA PRIVATE KEY",
|
||||
Bytes: x509.MarshalPKCS1PrivateKey(privateKey),
|
||||
}
|
||||
publicKey, err := gossh.NewPublicKey(&privateKey.PublicKey)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return pemKey, publicKey, err
|
||||
}
|
||||
|
||||
func NewECDSAKey(length uint) (*pem.Block, gossh.PublicKey, error) {
|
||||
var curve elliptic.Curve
|
||||
switch length {
|
||||
case 256:
|
||||
curve = elliptic.P256()
|
||||
case 384:
|
||||
curve = elliptic.P384()
|
||||
case 521:
|
||||
curve = elliptic.P521()
|
||||
default:
|
||||
return nil, nil, fmt.Errorf("key length not supported: %d, supported values are 256, 384, 521", length)
|
||||
}
|
||||
privateKey, err := ecdsa.GenerateKey(curve, rand.Reader)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
// convert priv key to x509 format
|
||||
marshaledKey, err := x509.MarshalPKCS8PrivateKey(privateKey)
|
||||
pemKey := &pem.Block{
|
||||
Type: "PRIVATE KEY",
|
||||
Bytes: marshaledKey,
|
||||
}
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
publicKey, err := gossh.NewPublicKey(&privateKey.PublicKey)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return pemKey, publicKey, err
|
||||
}
|
||||
|
||||
func NewEd25519Key() (*pem.Block, gossh.PublicKey, error) {
|
||||
publicKeyEd25519, privateKey, err := ed25519.GenerateKey(rand.Reader)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
// convert priv key to x509 format
|
||||
marshaledKey, err := x509.MarshalPKCS8PrivateKey(privateKey)
|
||||
pemKey := &pem.Block{
|
||||
Type: "PRIVATE KEY",
|
||||
Bytes: marshaledKey,
|
||||
}
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
publicKey, err := gossh.NewPublicKey(publicKeyEd25519)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return pemKey, publicKey, err
|
||||
}
|
||||
|
||||
func ImportSSHKey(keyValue string) (*dbmodels.SSHKey, error) {
|
||||
key := dbmodels.SSHKey{
|
||||
Type: "rsa",
|
||||
|
||||
@@ -38,7 +38,7 @@ type Setting struct {
|
||||
type SSHKey struct {
|
||||
// FIXME: use uuid for ID
|
||||
gorm.Model
|
||||
Name string `valid:"required,length(1|32),unix_user"`
|
||||
Name string `valid:"required,length(1|255),unix_user"`
|
||||
Type string `valid:"required"`
|
||||
Length uint `valid:"required"`
|
||||
Fingerprint string `valid:"optional"`
|
||||
@@ -51,7 +51,7 @@ type SSHKey struct {
|
||||
type Host struct {
|
||||
// FIXME: use uuid for ID
|
||||
gorm.Model
|
||||
Name string `gorm:"size:32" valid:"required,length(1|32)"`
|
||||
Name string `gorm:"size:255" valid:"required,length(1|255)"`
|
||||
Addr string `valid:"optional"` // FIXME: to be removed in a future version in favor of URL
|
||||
User string `valid:"optional"` // FIXME: to be removed in a future version in favor of URL
|
||||
Password string `valid:"optional"` // FIXME: to be removed in a future version in favor of URL
|
||||
@@ -78,7 +78,7 @@ type UserKey struct {
|
||||
|
||||
type UserRole struct {
|
||||
gorm.Model
|
||||
Name string `valid:"required,length(1|32),unix_user"`
|
||||
Name string `valid:"required,length(1|255),unix_user"`
|
||||
Users []*User `gorm:"many2many:user_user_roles"`
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ type User struct {
|
||||
gorm.Model
|
||||
Roles []*UserRole `gorm:"many2many:user_user_roles"`
|
||||
Email string `valid:"required,email"`
|
||||
Name string `valid:"required,length(1|32),unix_user"`
|
||||
Name string `valid:"required,length(1|255),unix_user"`
|
||||
Keys []*UserKey `gorm:"ForeignKey:UserID"`
|
||||
Groups []*UserGroup `gorm:"many2many:user_user_groups;"`
|
||||
Comment string `valid:"optional"`
|
||||
@@ -96,7 +96,7 @@ type User struct {
|
||||
|
||||
type UserGroup struct {
|
||||
gorm.Model
|
||||
Name string `valid:"required,length(1|32),unix_user"`
|
||||
Name string `valid:"required,length(1|255),unix_user"`
|
||||
Users []*User `gorm:"many2many:user_user_groups;"`
|
||||
ACLs []*ACL `gorm:"many2many:user_group_acls;"`
|
||||
Comment string `valid:"optional"`
|
||||
@@ -104,7 +104,7 @@ type UserGroup struct {
|
||||
|
||||
type HostGroup struct {
|
||||
gorm.Model
|
||||
Name string `valid:"required,length(1|32),unix_user"`
|
||||
Name string `valid:"required,length(1|255),unix_user"`
|
||||
Hosts []*Host `gorm:"many2many:host_host_groups;"`
|
||||
ACLs []*ACL `gorm:"many2many:host_group_acls;"`
|
||||
Comment string `valid:"optional"`
|
||||
|
||||
68
rules.mk
vendored
@@ -23,7 +23,8 @@
|
||||
# || | | | | | /_/_/_/\___/\_,_/_/ |
|
||||
# +--------------------------------------------------------------+
|
||||
|
||||
all: help
|
||||
.PHONY: _default_entrypoint
|
||||
_default_entrypoint: help
|
||||
|
||||
##
|
||||
## Common helpers
|
||||
@@ -31,6 +32,8 @@ all: help
|
||||
|
||||
rwildcard = $(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2) $(filter $(subst *,%,$2),$d))
|
||||
check-program = $(foreach exec,$(1),$(if $(shell PATH="$(PATH)" which $(exec)),,$(error "No $(exec) in PATH")))
|
||||
my-filter-out = $(foreach v,$(2),$(if $(findstring $(1),$(v)),,$(v)))
|
||||
novendor = $(call my-filter-out,vendor/,$(1))
|
||||
|
||||
##
|
||||
## rules.mk
|
||||
@@ -71,7 +74,7 @@ GO ?= go
|
||||
GOPATH ?= $(HOME)/go
|
||||
GO_INSTALL_OPTS ?=
|
||||
GO_TEST_OPTS ?= -test.timeout=30s
|
||||
GOMOD_DIR ?= .
|
||||
GOMOD_DIRS ?= $(sort $(call novendor,$(dir $(call rwildcard,*,*/go.mod go.mod))))
|
||||
GOCOVERAGE_FILE ?= ./coverage.txt
|
||||
GOTESTJSON_FILE ?= ./go-test.json
|
||||
GOBUILDLOG_FILE ?= ./go-build.log
|
||||
@@ -109,10 +112,11 @@ go.unittest:
|
||||
ifeq ($(CI),true)
|
||||
@echo "mode: atomic" > /tmp/gocoverage
|
||||
@rm -f $(GOTESTJSON_FILE)
|
||||
@set -e; for dir in `find $(GOMOD_DIR) -type f -name "go.mod" | grep -v /vendor/ | sed 's@/[^/]*$$@@' | sort | uniq`; do (set -e; (set -euf pipefail; \
|
||||
@set -e; for dir in $(GOMOD_DIRS); do (set -e; (set -euf pipefail; \
|
||||
cd $$dir; \
|
||||
($(GO) test ./... $(GO_TEST_OPTS) -cover -coverprofile=/tmp/profile.out -covermode=atomic -race -json | tee -a $(GOTESTJSON_FILE) 3>&1 1>&2 2>&3 | tee -a $(GOBUILDLOG_FILE); \
|
||||
(($(GO) test ./... $(GO_TEST_OPTS) -cover -coverprofile=/tmp/profile.out -covermode=atomic -race -json && touch $@.ok) | tee -a $(GOTESTJSON_FILE) 3>&1 1>&2 2>&3 | tee -a $(GOBUILDLOG_FILE); \
|
||||
); \
|
||||
rm $@.ok 2>/dev/null || exit 1; \
|
||||
if [ -f /tmp/profile.out ]; then \
|
||||
cat /tmp/profile.out | sed "/mode: atomic/d" >> /tmp/gocoverage; \
|
||||
rm -f /tmp/profile.out; \
|
||||
@@ -120,7 +124,7 @@ ifeq ($(CI),true)
|
||||
@mv /tmp/gocoverage $(GOCOVERAGE_FILE)
|
||||
else
|
||||
@echo "mode: atomic" > /tmp/gocoverage
|
||||
@set -e; for dir in `find $(GOMOD_DIR) -type f -name "go.mod" | grep -v /vendor/ | sed 's@/[^/]*$$@@' | sort | uniq`; do (set -e; (set -xe; \
|
||||
@set -e; for dir in $(GOMOD_DIRS); do (set -e; (set -xe; \
|
||||
cd $$dir; \
|
||||
$(GO) test ./... $(GO_TEST_OPTS) -cover -coverprofile=/tmp/profile.out -covermode=atomic -race); \
|
||||
if [ -f /tmp/profile.out ]; then \
|
||||
@@ -132,7 +136,7 @@ endif
|
||||
|
||||
.PHONY: go.checkdoc
|
||||
go.checkdoc:
|
||||
go doc $(GOMOD_DIR)
|
||||
go doc $(first $(GOMOD_DIRS))
|
||||
|
||||
.PHONY: go.coverfunc
|
||||
go.coverfunc: go.unittest
|
||||
@@ -140,46 +144,74 @@ go.coverfunc: go.unittest
|
||||
|
||||
.PHONY: go.lint
|
||||
go.lint:
|
||||
@set -e; for dir in `find $(GOMOD_DIR) -type f -name "go.mod" | grep -v /vendor/ | sed 's@/[^/]*$$@@' | sort | uniq`; do ( set -xe; \
|
||||
@set -e; for dir in $(GOMOD_DIRS); do ( set -xe; \
|
||||
cd $$dir; \
|
||||
golangci-lint run --verbose ./...; \
|
||||
); done
|
||||
|
||||
.PHONY: go.tidy
|
||||
go.tidy:
|
||||
@set -e; for dir in `find $(GOMOD_DIR) -type f -name "go.mod" | grep -v /vendor/ | sed 's@/[^/]*$$@@' | sort | uniq`; do ( set -xe; \
|
||||
@# tidy dirs with go.mod files
|
||||
@set -e; for dir in $(GOMOD_DIRS); do ( set -xe; \
|
||||
cd $$dir; \
|
||||
$(GO) mod tidy; \
|
||||
); done
|
||||
|
||||
.PHONY: go.depaware-update
|
||||
go.depaware-update: go.tidy
|
||||
@# gen depaware for bins
|
||||
@set -e; for dir in $(GOBINS); do ( set -xe; \
|
||||
cd $$dir; \
|
||||
$(GO) run github.com/tailscale/depaware --update .; \
|
||||
); done
|
||||
@# tidy unused depaware deps if not in a tools_test.go file
|
||||
@set -e; for dir in $(GOMOD_DIRS); do ( set -xe; \
|
||||
cd $$dir; \
|
||||
$(GO) mod tidy; \
|
||||
); done
|
||||
|
||||
.PHONY: go.depaware-check
|
||||
go.depaware-check: go.tidy
|
||||
@# gen depaware for bins
|
||||
@set -e; for dir in $(GOBINS); do ( set -xe; \
|
||||
cd $$dir; \
|
||||
$(GO) run github.com/tailscale/depaware --check .; \
|
||||
); done
|
||||
|
||||
|
||||
.PHONY: go.build
|
||||
go.build:
|
||||
@set -e; for dir in `find $(GOMOD_DIR) -type f -name "go.mod" | grep -v /vendor/ | sed 's@/[^/]*$$@@' | sort | uniq`; do ( set -xe; \
|
||||
@set -e; for dir in $(GOMOD_DIRS); do ( set -xe; \
|
||||
cd $$dir; \
|
||||
$(GO) build ./...; \
|
||||
); done
|
||||
|
||||
.PHONY: go.bump-deps
|
||||
go.bumpdeps:
|
||||
@set -e; for dir in `find $(GOMOD_DIR) -type f -name "go.mod" | grep -v /vendor/ | sed 's@/[^/]*$$@@' | sort | uniq`; do ( set -xe; \
|
||||
@set -e; for dir in $(GOMOD_DIRS); do ( set -xe; \
|
||||
cd $$dir; \
|
||||
$(GO) get -u ./...; \
|
||||
); done
|
||||
|
||||
.PHONY: go.bump-deps
|
||||
go.fmt:
|
||||
if ! command -v goimports &>/dev/null; then GO111MODULE=off go get golang.org/x/tools/cmd/goimports; fi
|
||||
@set -e; for dir in `find $(GOMOD_DIR) -type f -name "go.mod" | grep -v /vendor/ | sed 's@/[^/]*$$@@' | sort | uniq`; do ( set -xe; \
|
||||
@set -e; for dir in $(GOMOD_DIRS); do ( set -xe; \
|
||||
cd $$dir; \
|
||||
goimports -w `go list -f '{{.Dir}}' ./...)` \
|
||||
$(GO) run golang.org/x/tools/cmd/goimports -w `go list -f '{{.Dir}}' ./...` \
|
||||
); done
|
||||
|
||||
VERIFY_STEPS += go.depaware-check
|
||||
BUILD_STEPS += go.build
|
||||
BUMPDEPS_STEPS += go.bumpdeps
|
||||
BUMPDEPS_STEPS += go.bumpdeps go.depaware-update
|
||||
TIDY_STEPS += go.tidy
|
||||
LINT_STEPS += go.lint
|
||||
UNITTEST_STEPS += go.unittest
|
||||
FMT_STEPS += go.fmt
|
||||
|
||||
# FIXME: disabled, because currently slow
|
||||
# new rule that is manually run sometimes, i.e. `make pre-release` or `make maintenance`.
|
||||
# alternative: run it each time the go.mod is changed
|
||||
#GENERATE_STEPS += go.depaware-update
|
||||
endif
|
||||
|
||||
##
|
||||
@@ -285,6 +317,11 @@ ifdef BUILD_STEPS
|
||||
build: $(PRE_BUILD_STEPS) $(BUILD_STEPS)
|
||||
endif
|
||||
|
||||
ifdef VERIFY_STEPS
|
||||
.PHONY: verify
|
||||
verify: $(PRE_VERIFY_STEPS) $(VERIFY_STEPS)
|
||||
endif
|
||||
|
||||
ifdef RELEASE_STEPS
|
||||
.PHONY: release
|
||||
release: $(PRE_RELEASE_STEPS) $(RELEASE_STEPS)
|
||||
@@ -318,4 +355,7 @@ help::
|
||||
@[ "$(TEST_STEPS)" != "" ] && echo " test" || true
|
||||
@[ "$(TIDY_STEPS)" != "" ] && echo " tidy" || true
|
||||
@[ "$(UNITTEST_STEPS)" != "" ] && echo " unittest" || true
|
||||
@[ "$(VERIFY_STEPS)" != "" ] && echo " verify" || true
|
||||
@# FIXME: list other commands
|
||||
|
||||
print-% : ; $(info $* is a $(flavor $*) variable set to [$($*)]) @true
|
||||
|
||||