Browse Source

Checkpoint

master
maze 2 years ago
parent
commit
0d1fdad6fd
103 changed files with 24667 additions and 182 deletions
  1. +3
    -0
      .idea/.gitignore
  2. +5
    -0
      .idea/codeStyles/codeStyleConfig.xml
  3. +11
    -0
      .idea/gate.iml
  4. +6
    -0
      .idea/misc.xml
  5. +8
    -0
      .idea/modules.xml
  6. +6
    -0
      .idea/vcs.xml
  7. +29
    -0
      .idea/watcherTasks.xml
  8. +3
    -1
      cmd/gate/main.go
  9. +7
    -0
      etc/gate/auth/file.hcl
  10. +19
    -0
      etc/gate/auth/radius.hcl
  11. +10
    -0
      etc/gate/auth/yubikey.hcl
  12. +61
    -0
      etc/gate/credential/certificate.hcl
  13. +28
    -0
      etc/gate/credential/vault.hcl
  14. +43
    -121
      etc/gate/gate.hcl
  15. +3
    -0
      etc/gate/roles.hcl
  16. +36
    -0
      gate.toml
  17. +10
    -4
      go.mod
  18. +156
    -0
      go.sum
  19. +10
    -0
      gosec.json
  20. +53
    -0
      pkg/core/auth.go
  21. +61
    -9
      pkg/core/cli/config.go
  22. +25
    -0
      pkg/core/host.go
  23. +7
    -0
      pkg/core/runner.go
  24. +3
    -0
      pkg/core/service.go
  25. +16
    -1
      pkg/core/user.go
  26. +31
    -0
      pkg/crypto/authority/ca.go
  27. +95
    -0
      pkg/crypto/ksm/hsm.go
  28. +192
    -0
      pkg/crypto/ksm/ksm.go
  29. +88
    -0
      pkg/crypto/ksm/util.go
  30. +12
    -0
      pkg/db/db.go
  31. +121
    -0
      pkg/db/sqlite.go
  32. +28
    -0
      pkg/db/sqlite_test.go
  33. +23
    -0
      pkg/net/mdns/.gitignore
  34. +20
    -0
      pkg/net/mdns/LICENSE
  35. +37
    -0
      pkg/net/mdns/README.md
  36. +347
    -0
      pkg/net/mdns/client.go
  37. +288
    -0
      pkg/net/mdns/server.go
  38. +59
    -0
      pkg/net/mdns/server_test.go
  39. +307
    -0
      pkg/net/mdns/zone.go
  40. +275
    -0
      pkg/net/mdns/zone_test.go
  41. +2
    -1
      pkg/net/secureshell/server.go
  42. +15
    -5
      pkg/net/secureshell/transport.go
  43. +17
    -5
      pkg/net/web/auth.go
  44. +145
    -23
      pkg/net/web/server.go
  45. +350
    -0
      pkg/net/web/socket.go
  46. +1
    -0
      pkg/plugin/all/all.go
  47. +72
    -0
      pkg/plugin/common/common.go
  48. +25
    -10
      pkg/plugin/credential/cert.go
  49. +137
    -0
      pkg/plugin/hosts/hostfile.go
  50. +3
    -0
      pkg/plugin/hosts/hostfile_posix.go
  51. +3
    -0
      pkg/plugin/hosts/hosts_window.go
  52. +168
    -0
      pkg/plugin/hosts/mdns.go
  53. +64
    -0
      pkg/text/charset.go
  54. +193
    -0
      pkg/text/compare.go
  55. +19
    -0
      test/plugin-host/main.go
  56. +2
    -2
      testdata/groups
  57. +1
    -0
      testdata/users
  58. +1
    -0
      testdata/vault.token
  59. +17
    -0
      ui/.babelrc
  60. +9
    -0
      ui/.editorconfig
  61. +5
    -0
      ui/.eslintignore
  62. +29
    -0
      ui/.eslintrc.js
  63. +15
    -0
      ui/.gitignore
  64. +10
    -0
      ui/.postcssrc.js
  65. +27
    -0
      ui/README.md
  66. +41
    -0
      ui/build/build.js
  67. +54
    -0
      ui/build/check-versions.js
  68. BIN
      ui/build/logo.png
  69. +101
    -0
      ui/build/utils.js
  70. +22
    -0
      ui/build/vue-loader.conf.js
  71. +92
    -0
      ui/build/webpack.base.conf.js
  72. +95
    -0
      ui/build/webpack.dev.conf.js
  73. +149
    -0
      ui/build/webpack.prod.conf.js
  74. +7
    -0
      ui/config/dev.env.js
  75. +96
    -0
      ui/config/index.js
  76. +4
    -0
      ui/config/prod.env.js
  77. +7
    -0
      ui/config/test.env.js
  78. +14
    -0
      ui/index.html
  79. +18960
    -0
      ui/package-lock.json
  80. +87
    -0
      ui/package.json
  81. +114
    -0
      ui/src/App.vue
  82. +77
    -0
      ui/src/Sidebar.vue
  83. BIN
      ui/src/assets/logo.png
  84. +9
    -0
      ui/src/assets/theme.scss
  85. +34
    -0
      ui/src/backend/vue-axios/axios.js
  86. +8
    -0
      ui/src/backend/vue-axios/index.js
  87. +83
    -0
      ui/src/components/Dashboard.vue
  88. +81
    -0
      ui/src/components/Hosts.vue
  89. +152
    -0
      ui/src/components/SSH.vue
  90. +100
    -0
      ui/src/components/Transport.vue
  91. +79
    -0
      ui/src/components/Transports.vue
  92. +9
    -0
      ui/src/components/Tunnel.vue
  93. +25
    -0
      ui/src/main.js
  94. +23
    -0
      ui/src/models/User.js
  95. +57
    -0
      ui/src/router/index.js
  96. +40
    -0
      ui/src/store/auth.js
  97. +12
    -0
      ui/src/store/index.js
  98. +2
    -0
      ui/src/store/mutation-types.js
  99. +131
    -0
      ui/src/views/Login.vue
  100. +14
    -0
      ui/src/views/Logout.vue

+ 3
- 0
.idea/.gitignore View File

@ -0,0 +1,3 @@
# Default ignored files
/workspace.xml

+ 5
- 0
.idea/codeStyles/codeStyleConfig.xml View File

@ -0,0 +1,5 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
</state>
</component>

+ 11
- 0
.idea/gate.iml View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="Go" enabled="true" />
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Bundled Protobuf Distribution" level="application" />
</component>
</module>

+ 6
- 0
.idea/misc.xml View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="JavaScriptSettings">
<option name="languageLevel" value="JSX" />
</component>
</project>

+ 8
- 0
.idea/modules.xml View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/gate.iml" filepath="$PROJECT_DIR$/.idea/gate.iml" />
</modules>
</component>
</project>

+ 6
- 0
.idea/vcs.xml View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

+ 29
- 0
.idea/watcherTasks.xml View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectTasksOptions">
<TaskOptions isEnabled="true">
<option name="arguments" value="-local maze.io/gate -w $FilePath$" />
<option name="checkSyntaxErrors" value="true" />
<option name="description" />
<option name="exitCodeBehavior" value="ERROR" />
<option name="fileExtension" value="go" />
<option name="immediateSync" value="false" />
<option name="name" value="goimports" />
<option name="output" value="$FilePath$" />
<option name="outputFilters">
<array />
</option>
<option name="outputFromStdout" value="false" />
<option name="program" value="goimports" />
<option name="runOnExternalChanges" value="false" />
<option name="scopeName" value="Project Files" />
<option name="trackOnlyRoot" value="true" />
<option name="workingDir" value="$ProjectFileDir$" />
<envs>
<env name="GOROOT" value="$GOROOT$" />
<env name="GOPATH" value="$GOPATH$" />
<env name="PATH" value="$GoBinDirs$" />
</envs>
</TaskOptions>
</component>
</project>

+ 3
- 1
cmd/gate/main.go View File

@ -7,9 +7,11 @@ import (
"maze.io/gate/pkg/core/cli"
)
var DefaultConfig = "etc/gate/gate.hcl"
func main() {
var (
configFlag = flag.String("config", "gate.hcl", "configuration file")
configFlag = flag.String("config", DefaultConfig, "configuration file")
)
flag.Parse()


+ 7
- 0
etc/gate/auth/file.hcl View File

@ -0,0 +1,7 @@
file {
# Users file path, in UNIX passwd format
users = "testdata/users"
# Groups file path, in UNIX group format
groups = "testdata/groups"
}

+ 19
- 0
etc/gate/auth/radius.hcl View File

@ -0,0 +1,19 @@
radius {
# Server is the address of the RADIUS server
server = "127.0.0.1"
# Servers specifies the addresses of the RADIUS servers pool
#servers = ["10.0.0.1", "10.0.0.2"]
# Secret is the shared secret
secret = "testing"
# Station identifier, defaults to the hostname of the system
#station = "gate-001"
# Timeout specifies the request timeout
#timeout = "5s"
# Prompt for keyboard-interactive challenges
prompt = "Password: "
}

+ 10
- 0
etc/gate/auth/yubikey.hcl View File

@ -0,0 +1,10 @@
yubikey {
# Server specifies the YubiKey Validation API server
#server = "https://api.yubico.com"
# Servers specifies a pool of YubiKey Validation API servers
#servers = ["https://emea.auth.maze.network", "https://asia.auth.maze.network"]
# Prompt for keyboard-interactive challenges
prompt = "Token: "
}

+ 61
- 0
etc/gate/credential/certificate.hcl View File

@ -0,0 +1,61 @@
# The certificate credential provider generates ephemeral keys and signs a
# certificate for the target connection.
#
# This only works if:
# * The SSH server has the signing public key configured in
# `authorized_keys`, and/or:
# * The SSH server has the signing public key configured in the OpenSSH
# daemon, using the `TrustedUserCAKeys` stanza. See the `sshd_config`
# manual for more information.
certificate {
# Key for signing
key = "testdata/ssh_host_ed25519_key"
# Key for signing user certificates. If not specified, the key above is
# used.
#user_key = "testdata/user_ca_ed25519_key"
# Key for signing host certificates. If not specified, the key above is
# used.
#host_key = "testdata/host_ca_ed25519_key"
# Key type is the type of ephemeral key that is generated, valid values
# are:
# - ed25519
# - rsa2048
# - rsa4096
#
# The RSA types have better support, but the Ed25519 keys are
# computationally less expensive and offers better security than ECDSA
# and DSA.
key_type = "rsa2048"
# Prefix for the key ID.
# For example "@maze.network" to issue key ID's "login@maze.network".
#id_prefix = ""
# Suffix for the key ID.
# For example "MAZEIO\\" to issue key ID's "MAZEIO\login".
#id_suffix = ""
# Some implementations require the group to be encoded as principal.
groups_as_principals = true
/*
# Extensions is a map of group-to-extensions.
# The zero value ("") determines the default extensions.
extensions "" {
permit-X11-forwarding = ""
permit-agent-forwarding = ""
permit-port-forwarding = ""
permit-pty = ""
permit-user-rc = ""
}
# Options is a map of group-to-options.
# The zero value ("") determines the default options.
options "" {
# There are no default options.
}
*/
}

+ 28
- 0
etc/gate/credential/vault.hcl View File

@ -0,0 +1,28 @@
# The Vault provider makes use of the Vault SSH Secrets Engine.
# See https://www.vaultproject.io/docs/secrets/ssh/index.html
/*
vault {
# addr is the Vault address.
# It defaults to $VAULT_ADDR.
#addr = "https://127.0.0.1:8200"
# token is the Vault token.
# It defaults to $VAULT_TOKEN, if TokenFile is not set.
#token = "this is my secret vault token"
# token_file is a file that contains the Vault token.
#token_file = "/etc/gate/secret/vault.token"
# insecure disables TLS verification.
# It defaults to $VAULT_SKIP_VERIFY.
#insecure = true
# mount is the SSH Secrets Engine mount point.
# It defaults to "/ssh".
#mount = "/ssh"
# role is the Vault role.
# It defaults to "gate".
#role = "gate"
}
*/

gate.hcl → etc/gate/gate.hcl View File


+ 3
- 0
etc/gate/roles.hcl View File

@ -0,0 +1,3 @@
admin = {
group = "admin"
}

+ 36
- 0
gate.toml View File

@ -111,6 +111,42 @@ type = "file"
users = "testdata/users"
groups = "testdata/groups"
# policies
# ========
# matches ssh root target users:
[[policy.ssh.user]]
match = "root"
# use the "certificate" credential provider
credential = "certificate"
# permit groups and roles
permit_groups = ["admin", "staff", "wheel"]
permit_roles = ["admin"]
# match ssh test target users:
[[policy.ssh.user]]
match = "test*"
# reject groups
reject_groups = ["admin", "staff", "wheel"]
# matches all ssh target users:
[[policy.ssh.user]]
match = "*"
# use the "certificate" credential provider
credential = "certificate"
# match ssh localhost target hosts:
[policy.ssh.host."127.0.0.0/8"]
reject = { groups = ["admin", "staff", "wheel"] }
[policy.ssh.host."::1"]
reject = { groups = ["admin", "staff", "wheel"] }
# match any tcp target host:
[policy.tcp.host."0.0.0.0/0"]
permit_protos = ["ssh"]
# mesh clustering
# ===============
#[mesh.network]


+ 10
- 4
go.mod View File

@ -3,31 +3,37 @@ module maze.io/gate
go 1.13
require (
github.com/BurntSushi/toml v0.3.1 // indirect
github.com/GehirnInc/crypt v0.0.0-20190301055215-6c0105aabd46
github.com/ThalesIgnite/crypto11 v1.2.0 // indirect
github.com/c-bata/go-prompt v0.2.3
github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/golang/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.3.2
github.com/googollee/go-socket.io v1.4.2
github.com/gorilla/sessions v1.2.0
github.com/gorilla/websocket v1.4.1
github.com/hashicorp/golang-lru v0.5.3
github.com/hashicorp/hcl v1.0.0
github.com/hashicorp/mdns v1.0.1
github.com/hashicorp/memberlist v0.1.4
github.com/kr/pretty v0.1.0 // indirect
github.com/jmoiron/sqlx v1.2.0
github.com/labstack/echo-contrib v0.6.0
github.com/labstack/echo/v4 v4.1.10
github.com/mattn/go-runewidth v0.0.4 // indirect
github.com/mattn/go-sqlite3 v1.11.0
github.com/mattn/go-tty v0.0.0-20190424173100-523744f04859 // indirect
github.com/miekg/dns v1.0.14
github.com/mitchellh/mapstructure v1.1.2
github.com/natefinch/lumberjack v2.0.0+incompatible
github.com/pkg/term v0.0.0-20190109203006-aa71e9d9e942 // indirect
github.com/sirupsen/logrus v1.4.2
github.com/stretchr/testify v1.4.0
golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7
golang.org/x/net v0.0.0-20190909003024-a7b16738d86b // indirect
golang.org/x/net v0.0.0-20190909003024-a7b16738d86b
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45
golang.org/x/sync v0.0.0-20190423024810-112230192c58
golang.org/x/sys v0.0.0-20190911201528-7ad0cfa0b7b5
golang.org/x/text v0.3.2
google.golang.org/grpc v1.23.1
gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d // indirect
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
gopkg.in/ldap.v2 v2.5.1


+ 156
- 0
go.sum View File

@ -1,24 +1,65 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.36.0/go.mod h1:RUoy9p/M4ge0HzT8L+SDZ8jg+Q6fth0CiBuhFJpSV40=
dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU=
dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU=
dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4=
dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU=
git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/GehirnInc/crypt v0.0.0-20190301055215-6c0105aabd46 h1:rs0kDBt2zF4/CM9rO5/iH+U22jnTygPlqWgX55Ufcxg=
github.com/GehirnInc/crypt v0.0.0-20190301055215-6c0105aabd46/go.mod h1:kC29dT1vFpj7py2OvG1khBdQpo3kInWP+6QipLbdngo=
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
github.com/ThalesIgnite/crypto11 v1.2.0 h1:MNljmS3B9EmSFLZ4I7IFueeJNU5g869d7LcWvNrhv9Q=
github.com/ThalesIgnite/crypto11 v1.2.0/go.mod h1:vmlYtalkn8uCp3eStRZ0r7Sslmf1jAtL8De0PIyqPks=
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da h1:8GUt8eRujhVEGZFFEjBj46YV4rDjvGrNxb0KMWYkL2I=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g=
github.com/c-bata/go-prompt v0.2.3 h1:jjCS+QhG/sULBhAaBdjb2PlMRVaKXQgn+4yzaauvs2s=
github.com/c-bata/go-prompt v0.2.3/go.mod h1:VzqtzE2ksDBcdln8G7mk2RX9QyGjH+OVqOCSiVIqS34=
github.com/casbin/casbin v1.8.2/go.mod h1:z8uPsfBJGUsnkagrt3G8QvjgTKFMBJ32UP8HpZllfog=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
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=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E=
github.com/golang/lint v0.0.0-20181217174547-8f45f776aaf1/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c h1:964Od4U6p2jUkFxvCydnIczKteheJEzHRToSGK3Bnlw=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY=
github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg=
github.com/googollee/go-engine.io v1.4.1 h1:m3WlZAug1SODuWT++UX2nbzk9IUCn9T1SnmHoqppdqo=
github.com/googollee/go-engine.io v1.4.1/go.mod h1:26oFqHsnuWIzNOM0T08x21eQOydBosKOCgK3tyhzPPI=
github.com/googollee/go-socket.io v1.4.2 h1:yxoY4jyPp91ksh0IDBOLrphRXg6EXG+QUdveqg1RGSc=
github.com/googollee/go-socket.io v1.4.2/go.mod h1:yjlQxKcAZXZjpGwQVW/y1sgyL1ou+DdCpkswURDCRrU=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gordonklaus/ineffassign v0.0.0-20180909121442-1003c8bd00dc/go.mod h1:cuNKsD1zp2v6XfE/orVX2QE1LC+i254ceGcVeDT3pTU=
github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8=
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ=
@ -26,6 +67,12 @@ github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+
github.com/gorilla/sessions v1.1.3/go.mod h1:8KCfur6+4Mqcc6S0FEfKuN15Vl5MgXW92AE8ovaJD0w=
github.com/gorilla/sessions v1.2.0 h1:S7P+1Hm5V/AT9cjEcUD5uDaQSX0OE577aCXgoaKpYbQ=
github.com/gorilla/sessions v1.2.0/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM=
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw=
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-immutable-radix v1.0.0 h1:AKDB1HM5PWEA7i4nhcpwOrO2byshxBjXVn/J/3+z5/0=
@ -43,13 +90,20 @@ github.com/hashicorp/golang-lru v0.5.3 h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8
github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hashicorp/mdns v1.0.1 h1:XFSOubp8KWB+Jd2PDyaX5xUd5bhSP/+pTDZVDMzZJM8=
github.com/hashicorp/mdns v1.0.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg2DmyNY=
github.com/hashicorp/memberlist v0.1.4 h1:gkyML/r71w3FL8gUi74Vk76avkj/9lYAY9lvg0OcoGs=
github.com/hashicorp/memberlist v0.1.4/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU=
github.com/jmoiron/sqlx v1.2.0 h1:41Ip0zITnmWNR/vHV+S4m+VoUivnWY5E4OJfLZjCJMA=
github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/labstack/echo-contrib v0.6.0 h1:WT+TwJkJXrK+9n+x5VcI8f17VkUsiY33H5Mw3Pe8OfI=
@ -60,6 +114,7 @@ github.com/labstack/echo/v4 v4.1.10/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvf
github.com/labstack/gommon v0.2.9/go.mod h1:E8ZTmW9vw5az5/ZyHWCp0Lw4OH2ecsaBP1C/NKavGG4=
github.com/labstack/gommon v0.3.0 h1:JEeO0bvc78PKdyHxloTKiF8BD5iGrH8T6MSeGvSgob0=
github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k=
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
@ -67,24 +122,66 @@ github.com/mattn/go-isatty v0.0.9 h1:d5US/mDsogSGW37IV293h//ZFaeajb69h+EHFsv2xGg
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/p7Y=
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/mattn/go-sqlite3 v1.11.0 h1:LDdKkqtYlom37fkvqs8rMPFKAMe8+SgjbwZ6ex1/A/Q=
github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/mattn/go-tty v0.0.0-20190424173100-523744f04859 h1:smQbSzmT3EHl4EUwtFwFGmGIpiYgIiiPeVv1uguIQEE=
github.com/mattn/go-tty v0.0.0-20190424173100-523744f04859/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4=
github.com/miekg/dns v1.0.14 h1:9jZdLNd/P4+SfEJ0TNyxYpsK8N4GtfylBLqtbYN1sbA=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/miekg/pkcs11 v1.0.3-0.20190429190417-a667d056470f h1:eVB9ELsoq5ouItQBr5Tj334bhPJG/MX+m7rTchmzVUQ=
github.com/miekg/pkcs11 v1.0.3-0.20190429190417-a667d056470f/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/natefinch/lumberjack v2.0.0+incompatible h1:4QJd3OLAMgj7ph+yZTuX13Ld4UpgHp07nNdFX7mqFfM=
github.com/natefinch/lumberjack v2.0.0+incompatible/go.mod h1:Wi9p2TTF5DG5oU+6YfsmYQpsTIOm0B1VNzQg9Mw6nPk=
github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo=
github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM=
github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c h1:Lgl0gzECD8GnQ5QCWA8o6BtfL6mDH5rQgM4/fX3avOs=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/term v0.0.0-20190109203006-aa71e9d9e942 h1:A7GG7zcGjl3jqAqGPmcNjd/D9hzL95SuoOQAaFNdLU0=
github.com/pkg/term v0.0.0-20190109203006-aa71e9d9e942/go.mod h1:eCbImbZ95eXtAUIbLAuAVnBnwf83mjf6QIVH8SHYwqQ=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY=
github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM=
github.com/shurcooL/github_flavored_markdown v0.0.0-20181002035957-2122de532470/go.mod h1:2dOwnU2uBioM+SGy2aZoq1f/Sd1l9OkAeAUvjSyvgU0=
github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk=
github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ=
github.com/shurcooL/gofontwoff v0.0.0-20180329035133-29b52fc0a18d/go.mod h1:05UtEgK5zq39gLST6uB0cf3NEHjETfB4Fgr3Gx5R9Vw=
github.com/shurcooL/gopherjslib v0.0.0-20160914041154-feb6d3990c2c/go.mod h1:8d3azKNyqcHP1GaQE/c6dDgjkgSx2BZ4IoEi4F1reUI=
github.com/shurcooL/highlight_diff v0.0.0-20170515013008-09bb4053de1b/go.mod h1:ZpfEhSmds4ytuByIcDnOLkTHGUI6KNqRNPDLHDk+mUU=
github.com/shurcooL/highlight_go v0.0.0-20181028180052-98c3abbbae20/go.mod h1:UDKB5a1T23gOMUJrI+uSuH0VRDStOiUVSjBTRDVBVag=
github.com/shurcooL/home v0.0.0-20181020052607-80b7ffcb30f9/go.mod h1:+rgNQw2P9ARFAs37qieuu7ohDNQ3gds9msbT2yn85sg=
github.com/shurcooL/htmlg v0.0.0-20170918183704-d01228ac9e50/go.mod h1:zPn1wHpTIePGnXSHpsVPWEktKXHr6+SS6x/IKRb7cpw=
github.com/shurcooL/httperror v0.0.0-20170206035902-86b7830d14cc/go.mod h1:aYMfkZ6DWSJPJ6c4Wwz3QtW22G7mf/PEgaB9k/ik5+Y=
github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
github.com/shurcooL/httpgzip v0.0.0-20180522190206-b1c53ac65af9/go.mod h1:919LwcH0M7/W4fcZ0/jy0qGght1GIhqyS/EgWGH2j5Q=
github.com/shurcooL/issues v0.0.0-20181008053335-6292fdc1e191/go.mod h1:e2qWDig5bLteJ4fwvDAc2NHzqFEthkqn7aOZAOpj+PQ=
github.com/shurcooL/issuesapp v0.0.0-20180602232740-048589ce2241/go.mod h1:NPpHK2TI7iSaM0buivtFUc9offApnI0Alt/K8hcHy0I=
github.com/shurcooL/notifications v0.0.0-20181007000457-627ab5aea122/go.mod h1:b5uSkrEVM1jQUspwbixRBhaIjIzL2xazXp6kntxYle0=
github.com/shurcooL/octicon v0.0.0-20181028054416-fa4f57f9efb2/go.mod h1:eWdoE5JD4R5UVWDucdOPg1g2fqQRq78IQa9zlOV1vpQ=
github.com/shurcooL/reactions v0.0.0-20181006231557-f2e0b4ca5b82/go.mod h1:TCR1lToEk4d2s07G3XGfz2QrgHXg4RJBvjrOozvoWfk=
github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4=
github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw=
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE=
github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
@ -93,19 +190,36 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA=
github.com/thales-e-security/pool v0.0.1 h1:1eJJNN2K/mAzwfr546brAiQVa3UaRC0gGENsHM8veS8=
github.com/thales-e-security/pool v0.0.1/go.mod h1:qtpMm2+thHtqhLzTwgDBj/OuNnMpupY8mv0Phz0gjhU=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasttemplate v1.0.1 h1:tY9CJiPnMXf1ERmG2EyK7gNUd+c6RKGD0IfU8WdUSz8=
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA=
go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE=
golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw=
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/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-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7 h1:0hQKqeLdqlt5iIwVOBErRisrHJAN57yOiPRQItI20fU=
golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/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 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
@ -113,12 +227,21 @@ golang.org/x/net v0.0.0-20190607181551-461777fb6f67 h1:rJJxsykSlULwd2P2+pg/rtnwN
golang.org/x/net v0.0.0-20190607181551-461777fb6f67/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190909003024-a7b16738d86b h1:XfVGCX+0T4WOStkaOsJRllbsiImhB2jgVBGc9L0lPGc=
golang.org/x/net v0.0.0-20190909003024-a7b16738d86b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@ -133,25 +256,56 @@ golang.org/x/sys v0.0.0-20190911201528-7ad0cfa0b7b5 h1:SW/0nsKCUaozCUtZTakri5lao
golang.org/x/sys v0.0.0-20190911201528-7ad0cfa0b7b5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190214204934-8dcb7bc8c7fe/go.mod h1:E6PF97AdD6v0s+fPshSmumCW1S1Ne85RbPQxELkKa44=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190608022120-eacb66d2a7c3/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190610214847-0945d3616f18/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8 h1:Nw54tB0rB7hY/N0NQvRW8DG4Yk3Q6T9cu9RcFQDu1tc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg=
google.golang.org/genproto v0.0.0-20190201180003-4b09977fb922/go.mod h1:L3J43x8/uS+qIUoksaLKe6OS3nUKxOKuIFz1sl2/jx4=
google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio=
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
google.golang.org/grpc v1.23.1 h1:q4XQuHFC6I28BKZpo6IYyb3mNO+l7lSOxRuYTCiDfXk=
google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d h1:TxyelI5cVkbREznMhfzycHdkp5cLA7DpE+GKjSslYhM=
gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw=
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/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/ldap.v2 v2.5.1 h1:wiu0okdNfjlBzg6UWvd1Hn8Y+Ux17/u/4nlk4CQr6tU=
gopkg.in/ldap.v2 v2.5.1/go.mod h1:oI0cpe/D7HRtBQl8aTg+ZmzFUAvu4lsv3eLXMLGFxWk=
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o=
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
layeh.com/radius v0.0.0-20190322222518-890bc1058917 h1:BDXFaFzUt5EIqe/4wrTc4AcYZWP6iC6Ult+jQWLh5eU=
layeh.com/radius v0.0.0-20190322222518-890bc1058917/go.mod h1:fywZKyu//X7iRzaxLgPWsvc0L26IUpVvE/aeIL2JtIQ=
maze.io/x/asciicast v1.0.1 h1:oYekeRlWiFu4PSxrCLC5hBDjgRm3KMFOi57YmFMjbg4=
@ -160,3 +314,5 @@ maze.io/x/otp v0.0.0-20190910213007-b6cf3cc7246a h1:QbersYNc6Zwr03mawjeX50PCA15e
maze.io/x/otp v0.0.0-20190910213007-b6cf3cc7246a/go.mod h1:WdKOzlyiJegybpv2TdYGxW/QSHzn2zZUEp6Hc9jut4o=
maze.io/x/secureshell v1.0.8 h1:cu4pY0KQd9u6hK4vsyJdOIEjGy0Crj04F8S+TVjXozw=
maze.io/x/secureshell v1.0.8/go.mod h1:jD54Uod5w7PCNrQgoP87iHQF8JyyB7E9XRymFKrXmsU=
sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck=
sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0=

+ 10
- 0
gosec.json View File

@ -0,0 +1,10 @@
{
"G104": {
"maze.io/gate/pkg/crypto/crypt": [
"Generate"
],
"maze.io/gate/pkg/text/terminfo/dynamic": [
"unescape"
]
}
}

+ 53
- 0
pkg/core/auth.go View File

@ -16,11 +16,15 @@ const DefaultAuthenticationProviderName = "system"
// DefaultCredentialProviderName is the name of the default credential provider.
const DefaultCredentialProviderName = "agent"
// DefaultHostsProviderName is the name of the default hosts provider.
const DefaultHostsProviderName = "hostfile"
// Providers is a collection of configured providers.
type Providers struct {
Identity IdentityProvider
Authentication map[string]AuthenticationProvider
Credential map[string]CredentialProvider
Hosts map[string]HostsProvider
}
// AuthenticationProviderConfig is the configuration structure for "auth" blocks.
@ -170,3 +174,52 @@ func NewCredentialProvider(name string, config map[string]interface{}, log *logg
}
return provider, nil
}
// HostsProviderConfig is the configuration structure for "hosts" blocks.
type HostsProviderConfig map[string]map[string]interface{}
// Providers returns the configured credential providers keyed by name.
func (config HostsProviderConfig) Providers(log *logger.Logger) (map[string]HostsProvider, error) {
var (
providers = make(map[string]HostsProvider)
names []string
)
if config == nil {
p, err := NewHostsProvider(DefaultHostsProviderName, nil, log)
if err != nil {
return nil, err
}
providers[DefaultHostsProviderName] = p
names = append(names, DefaultHostsProviderName)
} else {
for name, componentConfig := range config {
p, err := NewHostsProvider(name, componentConfig, log)
if err != nil {
return nil, err
}
providers[name] = p
names = append(names, name)
}
}
log.WithField("providers", names).Debug("loaded hosts providers")
return providers, nil
}
// NewHostsProvider loads a hosts provider by name.
func NewHostsProvider(name string, config map[string]interface{}, log *logger.Logger) (HostsProvider, error) {
log.WithField(logger.Component, name).Debug("loading hosts provider")
component, err := LoadPlugin(name)
if err != nil {
return nil, err
}
provider, ok := component.(HostsProvider)
if !ok {
return nil, fmt.Errorf("core: component %q does not implement HostsProvider", name)
}
if err := provider.Setup(config, log); err != nil {
return nil, err
}
return provider, nil
}

+ 61
- 9
pkg/core/cli/config.go View File

@ -4,6 +4,7 @@ import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"github.com/hashicorp/hcl"
@ -18,15 +19,21 @@ import (
// Config is the top configuration structure.
type Config struct {
Mesh *mesh.Mesh `hcl:"mesh" toml:"mesh"`
SecureShell *secureshell.Server `hcl:"sshd" toml:"sshd"`
Web *web.Server `hcl:"httpd" toml:"httpd"`
Log logger.Config `hcl:"log" toml:"log"`
Auth core.AuthenticationProviderConfig `hcl:"auth" toml:"auth"`
Identity core.IdentityProviderConfig `hcl:"identity" toml:"identity"`
Credential core.CredentialProviderConfig `hcl:"credential" toml:"credential"`
Roles core.Roles `hcl:"roles" toml:"roles"`
Recorder *recorder.Recorder `hcl:"recorder" toml:"recorder"`
Mesh *mesh.Mesh `hcl:"mesh"`
SecureShell *secureshell.Server `hcl:"sshd"`
Web *web.Server `hcl:"httpd"`
Log logger.Config `hcl:"log"`
Auth core.AuthenticationProviderConfig `hcl:"auth"`
AuthInclude []string `hcl:"auth_include"`
Identity core.IdentityProviderConfig `hcl:"identity"`
IdentityInclude []string `hcl:"identity_include"`
Credential core.CredentialProviderConfig `hcl:"credential"`
CredentialInclude []string `hcl:"credential_include"`
Role core.Roles `hcl:"role"`
RoleInclude []string `hcl:"role_include"`
Hosts core.HostsProviderConfig `hcl:"hosts"`
HostsInclude []string `hcl:"hosts_include"`
Recorder *recorder.Recorder `hcl:"recorder" toml:"recorder"`
}
// LoadConfig reads the configuration file from disk and parses the configuration structure.
@ -46,9 +53,51 @@ func LoadConfig(name string) (*Config, error) {
if err = hcl.Unmarshal(configData, config); err != nil {
return nil, fmt.Errorf("config: error parsing %s: %w", name, err)
}
if len(config.HostsInclude) > 0 {
if err = loadIncludes(config.HostsInclude, &config.Hosts); err != nil {
return nil, fmt.Errorf("config: error parsing hosts_include: %w", err)
}
}
if len(config.AuthInclude) > 0 {
if err = loadIncludes(config.AuthInclude, &config.Auth); err != nil {
return nil, fmt.Errorf("config: error parsing auth_include: %w", err)
}
}
if len(config.CredentialInclude) > 0 {
if err = loadIncludes(config.CredentialInclude, &config.Credential); err != nil {
return nil, fmt.Errorf("config: error parsing credential_include: %w", err)
}
}
if len(config.RoleInclude) > 0 {
if err = loadIncludes(config.RoleInclude, &config.Role); err != nil {
return nil, fmt.Errorf("config: error parsing role_include: %w", err)
}
}
return config, nil
}
func loadIncludes(patterns []string, value interface{}) (err error) {
for _, pattern := range patterns {
var names []string
if names, err = filepath.Glob(pattern); err != nil {
return fmt.Errorf("error expanding %s: %w", pattern, err)
}
for _, name := range names {
var includeData []byte
if includeData, err = ioutil.ReadFile(name); err != nil { // #nosec
return fmt.Errorf("error reading %s: %w", name, err)
}
if err = hcl.Unmarshal(includeData, value); err != nil {
return fmt.Errorf("error parsing %s: %w", name, err)
}
}
}
return
}
// Logger returns a configured Logger.
func (config *Config) Logger() *logger.Logger {
log := logger.New(os.Stdout)
@ -63,6 +112,9 @@ func (config *Config) Providers() (*core.Providers, error) {
providers = new(core.Providers)
err error
)
if providers.Hosts, err = config.Hosts.Providers(logger.Default); err != nil {
return nil, err
}
if providers.Authentication, err = config.Auth.Providers(logger.Default); err != nil {
return nil, err
}


+ 25
- 0
pkg/core/host.go View File

@ -0,0 +1,25 @@
package core
import "net"
type Host struct {
// Name is the full qualified hostname.
Name string `json:"name"`
// Aliases for this host.
Aliases []string `json:"aliases,omitempty"`
// IPs are the IP addresses.
IPs []net.IP `json:"ips,omitempty"`
}
type HostsProvider interface {
Plugin
// Hosts returns all available hosts.
Hosts() []Host
// MatchHost returns a slice of host that match the glob pattern.
// If limit <= 0, no limit is applied.
MatchHost(pattern string, limit int) []Host
}

+ 7
- 0
pkg/core/runner.go View File

@ -78,6 +78,13 @@ func (r *Runner) startProviders() (err error) {
return
}
r.log.WithField("providers", len(r.Providers.Hosts)).Debug("starting hosts providers")
for _, provider := range r.Providers.Hosts {
if err = r.startProvider(provider); err != nil {
return
}
}
r.log.WithField("providers", len(r.Providers.Authentication)).Debug("starting authentication providers")
for _, provider := range r.Providers.Authentication {
if err = r.startProvider(provider); err != nil {


+ 3
- 0
pkg/core/service.go View File

@ -65,6 +65,9 @@ type AgentTransporter interface {
type Tunnel interface {
net.Conn
// TunnelID is the globally unique identifier.
TunnelID() compact.ID
// User is the authenticated user on this transport.
User() User


+ 16
- 1
pkg/core/user.go View File

@ -1,6 +1,10 @@
package core
import "maze.io/gate/pkg/util/compact"
import (
"os/user"
"maze.io/gate/pkg/util/compact"
)
// User entity.
type User interface {
@ -16,3 +20,14 @@ type User interface {
// Groups is a slice of groups this user is a member of.
Groups() []Group
}
func IsUserNotFound(err error) bool {
switch err.(type) {
case user.UnknownUserError:
return true
case user.UnknownUserIdError:
return true
default:
return false
}
}

+ 31
- 0
pkg/crypto/authority/ca.go View File

@ -0,0 +1,31 @@
package authority
import (
"crypto/rand"
"fmt"
"golang.org/x/crypto/ssh"
)
type CertificateAuthority struct {
hostKeySigner ssh.Signer
userKeySigner ssh.Signer
}
func New(hostKey, userKey ssh.Signer) *CertificateAuthority {
return &CertificateAuthority{
hostKeySigner: hostKey,
userKeySigner: userKey,
}
}
func (ca *CertificateAuthority) Sign(certificate *ssh.Certificate) error {
switch certificate.CertType {
case ssh.UserCert:
return certificate.SignCert(rand.Reader, ca.userKeySigner)
case ssh.HostCert:
return certificate.SignCert(rand.Reader, ca.hostKeySigner)
default:
return fmt.Errorf("authority: unsupported certificate type %d", certificate.CertType)
}
}

+ 95
- 0
pkg/crypto/ksm/hsm.go View File

@ -0,0 +1,95 @@
package ksm
import (
"crypto"
"crypto/elliptic"
"github.com/ThalesIgnite/crypto11"
"github.com/mitchellh/mapstructure"
"golang.org/x/crypto/ssh"
"maze.io/gate/pkg/core"
"maze.io/gate/pkg/core/logger"
)
type hsm struct {
// Full path to PKCS#11 library.
Path string
// Token serial number.
TokenSerial string `mapstructure:"serial"`
// Token label.
TokenLabel string `mapstructure:"label"`
// SlotNumber identifies a token to use by the slot containing it.
SlotNumber *int `mapstructure:"slot"`
// User PIN (password).
Pin string
log *logger.Logger
ctx *crypto11.Context
}
func (hsm) Component() string {
return "hsm"
}
func (backend *hsm) Setup(config map[string]interface{}, log *logger.Logger) (err error) {
backend.log = log.WithField(logger.Component, backend.Component())
if err = mapstructure.Decode(config, backend); err != nil {
return err
}
if backend.ctx, err = crypto11.Configure(&crypto11.Config{
Path: backend.Path,
TokenSerial: backend.TokenSerial,
TokenLabel: backend.TokenLabel,
SlotNumber: backend.SlotNumber,
Pin: backend.Pin,
}); err != nil {
return err
}
return nil
}
func (hsm) Start(_ *core.Runner) error {
return nil
}
func (backend *hsm) NewSigner(name string, keyAlgorithm string, bits int) (ssh.Signer, error) {
var (
id = []byte(name)
signer crypto.Signer
err error
)
switch keyAlgorithm {
case ssh.KeyAlgoRSA:
signer, err = backend.ctx.GenerateRSAKeyPairWithLabel(id, id, bits)
case ssh.KeyAlgoECDSA256:
signer, err = backend.ctx.GenerateECDSAKeyPairWithLabel(id, id, elliptic.P256())
case ssh.KeyAlgoECDSA384:
signer, err = backend.ctx.GenerateECDSAKeyPairWithLabel(id, id, elliptic.P384())
case ssh.KeyAlgoECDSA521:
signer, err = backend.ctx.GenerateECDSAKeyPairWithLabel(id, id, elliptic.P521())
}
if err != nil {
return nil, err
}
return ssh.NewSignerFromSigner(signer)
}
func (backend *hsm) GetSigner(name string) (ssh.Signer, error) {
s, err := backend.ctx.FindKeyPair(nil, []byte(name))
if err != nil {
return nil, err
}
return ssh.NewSignerFromSigner(s)
}
var (
_ core.Plugin = (*hsm)(nil)
_ Backend = (*hsm)(nil)
)

+ 192
- 0
pkg/crypto/ksm/ksm.go View File

@ -0,0 +1,192 @@
package ksm
import (
"crypto/ecdsa"
"crypto/ed25519"
"crypto/elliptic"
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/pem"
"fmt"
"io"
"io/ioutil"
"os"
"path/filepath"
"strings"
"github.com/mitchellh/mapstructure"
"golang.org/x/crypto/ssh"
"maze.io/gate/pkg/core"
"maze.io/gate/pkg/core/logger"
)
// Backend can store SSH private keys.
type Backend interface {
// NewSigner creates a new signer.
NewSigner(name string, keyAlgorithm string, bits int) (ssh.Signer, error)
// GetSigner gets a signer by name.
GetSigner(name string) (ssh.Signer, error)
}
type disk struct {
Path string
log *logger.Logger
random io.Reader
}
func (disk) Component() string {
return "ksm.disk"
}
func (backend *disk) Setup(config map[string]interface{}, log *logger.Logger) error {
backend.log = log.WithField(logger.Component, backend.Component())
backend.random = rand.Reader
if err := mapstructure.Decode(config, backend); err != nil {
return err
}
if !filepath.IsAbs(backend.Path) {
var err error
if backend.Path, err = filepath.Abs(backend.Path); err != nil {
return fmt.Errorf("ksm: error resolving %s: %w", backend.Path, err)
}
}
i, err := os.Stat(backend.Path)
if err != nil {
return err
} else if !i.IsDir() {
return fmt.Errorf("ksm: %s is not a directory", backend.Path)
} else if i.Mode()&007 != 0 {
return fmt.Errorf("ksm: %s is other accessible (mode %s)", backend.Path, i.Mode())
}
return nil
}
func (backend *disk) Start(_ *core.Runner) error {
return nil
}
func (backend *disk) NewSigner(name string, keyAlgorithm string, bits int) (ssh.Signer, error) {
algorithm := keyAlgorithm
if !strings.HasPrefix(algorithm, "ssh-") {
algorithm = "ssh-" + algorithm
}
switch algorithm {
case ssh.KeyAlgoRSA:
return backend.newRSASigner(name, bits)
case ssh.KeyAlgoECDSA256:
return backend.newECDSASigner(name, 256)
case ssh.KeyAlgoECDSA384:
return backend.newECDSASigner(name, 384)
case ssh.KeyAlgoECDSA521:
return backend.newECDSASigner(name, 521)
case ssh.KeyAlgoED25519:
return backend.newEd25519Signer(name)
default:
return nil, fmt.Errorf("ksm: unsupported key algorithm %q specified", keyAlgorithm)
}
}
func (backend *disk) newRSASigner(name string, bits int) (ssh.Signer, error) {
if bits < 2048 {
bits = 2048
}
k, err := rsa.GenerateKey(backend.random, bits)
if err != nil {
return nil, err
} else if err = k.Validate(); err != nil {
return nil, err
}
if err = backend.store(name, "RSA PRIVATE KEY", x509.MarshalPKCS1PrivateKey(k)); err != nil {
return nil, err
}
return ssh.NewSignerFromKey(k)
}
func (backend *disk) newECDSASigner(name string, bits int) (ssh.Signer, error) {
var curve elliptic.Curve
switch bits {
case 0, 256:
curve = elliptic.P256()
case 384:
curve = elliptic.P384()
case 521:
curve = elliptic.P521()
default:
return nil, fmt.Errorf("ksm: unsupported ECDSA key size %d-bits (valid are 256, 834 or 521)", bits)
}
k, err := ecdsa.GenerateKey(curve, backend.random)
if err != nil {
return nil, err
}
derBytes, err := x509.MarshalECPrivateKey(k)
if err != nil {
return nil, err
}
if err = backend.store(name, "EC PRIVATE KEY", derBytes); err != nil {
return nil, err
}
return ssh.NewSignerFromKey(k)
}
func (backend *disk) newEd25519Signer(name string) (ssh.Signer, error) {
_, k, err := ed25519.GenerateKey(backend.random)
if err != nil {
return nil, err
}
if err = backend.store(name, "OPENSSH PRIVATE KEY", marshalED25519PrivateKey(k)); err != nil {
return nil, err
}
return ssh.NewSignerFromKey(k)
}
func (backend *disk) store(name string, pemType string, derBytes []byte) error {
f, err := os.OpenFile(filepath.Join(backend.Path, name), os.O_WRONLY|os.O_CREATE, 0600)
if err != nil {
return err
}
if _, err = f.Write(pem.EncodeToMemory(&pem.Block{
Type: pemType,
Bytes: derBytes,
})); err != nil {
_ = f.Close()
return err
}
if err = f.Close(); err != nil {
_ = os.Remove(filepath.Join(backend.Path, name))
return err
}
return nil
}
func (backend *disk) GetSigner(name string) (ssh.Signer, error) {
b, err := ioutil.ReadFile(filepath.Join(backend.Path, name))
if err != nil {
return nil, err
}
return ssh.ParsePrivateKey(b)
}
var (
_ core.Plugin = (*disk)(nil)
_ Backend = (*disk)(nil)
)

+ 88
- 0
pkg/crypto/ksm/util.go View File

@ -0,0 +1,88 @@
package ksm
import (
"math/rand"
"golang.org/x/crypto/ed25519"
"golang.org/x/crypto/ssh"
)
/* Writes ed25519 private keys into the new OpenSSH private key format.
I have no idea why this isn't implemented anywhere yet, you can do seemingly
everything except write it to disk in the OpenSSH private key format. */
func marshalED25519PrivateKey(key ed25519.PrivateKey) []byte {
// Add our key header (followed by a null byte)
magic := append([]byte("openssh-key-v1"), 0)
var w struct {
CipherName string
KdfName string
KdfOpts string
NumKeys uint32
PubKey []byte
PrivKeyBlock []byte
}
// Fill out the private key fields
pk1 := struct {
Check1 uint32
Check2 uint32
Keytype string
Pub []byte
Priv []byte
Comment string
Pad []byte `ssh:"rest"`
}{}
// Set our check ints
ci := rand.Uint32()
pk1.Check1 = ci
pk1.Check2 = ci
// Set our key type
pk1.Keytype = ssh.KeyAlgoED25519
// Add the pubkey to the optionally-encrypted block
pk, ok := key.Public().(ed25519.PublicKey)
if !ok {
//fmt.Fprintln(os.Stderr, "ed25519.PublicKey type assertion failed on an ed25519 public key. This should never ever happen.")
return nil
}
pubKey := []byte(pk)
pk1.Pub = pubKey
// Add our private key
pk1.Priv = []byte(key)
// Might be useful to put something in here at some point
pk1.Comment = ""
// Add some padding to match the encryption block size within PrivKeyBlock (without Pad field)
// 8 doesn't match the documentation, but that's what ssh-keygen uses for unencrypted keys. *shrug*
bs := 8
blockLen := len(ssh.Marshal(pk1))
padLen := (bs - (blockLen % bs)) % bs
pk1.Pad = make([]byte, padLen)
// Padding is a sequence of bytes like: 1, 2, 3...
for i := 0; i < padLen; i++ {
pk1.Pad[i] = byte(i + 1)
}
// Generate the pubkey prefix "\0\0\0\nssh-ed25519\0\0\0 "
prefix := []byte{0x0, 0x0, 0x0, 0x0b}
prefix = append(prefix, []byte(ssh.KeyAlgoED25519)...)
prefix = append(prefix, []byte{0x0, 0x0, 0x0, 0x20}...)
// Only going to support unencrypted keys for now
w.CipherName = "none"
w.KdfName = "none"
w.KdfOpts = ""
w.NumKeys = 1
w.PubKey = append(prefix, pubKey...)
w.PrivKeyBlock = ssh.Marshal(pk1)
magic = append(magic, ssh.Marshal(w)...)
return magic
}

+ 12
- 0
pkg/db/db.go View File

@ -0,0 +1,12 @@
package db
type Backend interface {
// Delete a setting by name.
Delete(key string) (ok bool, err error)
// Get a setting by name, passing the value back.
Get(key string, value interface{}) error
// Set a setting by name.
Set(key string, value interface{}) error
}

+ 121
- 0
pkg/db/sqlite.go View File

@ -0,0 +1,121 @@
package db
import (
"bytes"
"database/sql"
"encoding/gob"
"github.com/jmoiron/sqlx"
_ "github.com/mattn/go-sqlite3" // SQLite3 driver
)
type sqliteBackend struct {
db *sqlx.DB
}
func NewSQLite(name string) (Backend, error) {
db, err := sqlx.Connect("sqlite3", name)
if err != nil {
return nil, err
}
if _, err = db.Exec(sqliteSchema); err != nil {
_ = db.Close()
return nil, err
}
return &sqliteBackend{
db: db,
}, nil
}
// Delete a setting by name.
func (driver *sqliteBackend) Delete(key string) (ok bool, err error) {
var result sql.Result
if result, err = driver.db.Exec(sqliteSettingDelete, key); err != nil {
return
}
var rows int64
if rows, err = result.RowsAffected(); err != nil {
return
}
return rows > 0, nil
}
func (driver *sqliteBackend) Get(key string, value interface{}) error {
var (
result = driver.db.QueryRow(sqliteSettingGet, key)
timestamp int64
encodedValue []byte
)
if err := result.Scan(&timestamp, &encodedValue); err != nil {
return err
}
var (
buffer = bytes.NewBuffer(encodedValue)
decoder = gob.NewDecoder(buffer)
)
return decoder.Decode(value)
}
func (driver *sqliteBackend) Set(key string, value interface{}) error {
var (
buffer bytes.Buffer
encoder = gob.NewEncoder(&buffer)
)
if err := encoder.Encode(value); err != nil {
return err
}
if _, err := driver.db.Exec(sqliteSettingSet, key, buffer.Bytes()); err != nil {
return err
}
return nil
}
const (
sqliteSchema = `
CREATE TABLE IF NOT EXISTS auth_user (
id INTEGER PRIMARY KEY AUTOINCREMENT,
login VARCHAR(64),
password VARCHAR(128),
email VARCHAR(256),
is_active BOOL
);
CREATE TABLE IF NOT EXISTS auth_group (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name VARCHAR(64)
);
CREATE TABLE IF NOT EXISTS auth_group_users (
auth_group_id INTEGER,
auth_user_id INTEGER
);
CREATE TABLE IF NOT EXISTS auth_role (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name VARCHAR(64)
);
CREATE TABLE IF NOT EXISTS auth_role_users (
auth_role_id INTEGER,
auth_user_id INTEGER
);
CREATE TABLE IF NOT EXISTS auth_role_groups (
auth_role_id INTEGER,
auth_group_id INTEGER
);
CREATE TABLE IF NOT EXISTS setting (
id INTEGER PRIMARY KEY AUTOINCREMENT,
created_at INTEGER,
setting_key VARCHAR(64),
setting_value BLOB
);
`
sqliteSettingDelete = `DELETE FROM setting WHERE setting_key = ?;`
sqliteSettingGet = `SELECT created_at, setting_value FROM setting WHERE setting_key = ?;`
sqliteSettingSet = `INSERT INTO setting (created_at, setting_key, setting_value) VALUES (strftime('%s','now'), ?, ?);`
)

+ 28
- 0
pkg/db/sqlite_test.go View File

@ -0,0 +1,28 @@
package db
import "testing"
func TestSQLite(t *testing.T) {
b, err := NewSQLite(":memory:")
if err != nil {
t.Fatal(err)
}
if err = b.Set("test", "test"); err != nil {
t.Fatal(err)
}
var testString string
if err = b.Get("test", &testString); err != nil {
t.Fatal(err)
} else if testString != "test" {
t.Fatalf("expected %q, got %q", "test", testString)
}
var ok bool
if ok, err = b.Delete("test"); err != nil {
t.Fatal(err)
} else if !ok {
t.Error("expected setting \"test\" to exist")
}
}

+ 23
- 0
pkg/net/mdns/.gitignore View File

@ -0,0 +1,23 @@
# Compiled Object files, Static and Dynamic libs (Shared Objects)
*.o
*.a
*.so
# Folders
_obj
_test
# Architecture specific extensions/prefixes
*.[568vq]
[568vq].out
*.cgo1.go
*.cgo2.c
_cgo_defun.c
_cgo_gotypes.go
_cgo_export.*
_testmain.go
*.exe
*.test

+ 20
- 0
pkg/net/mdns/LICENSE View File

@ -0,0 +1,20 @@
The MIT License (MIT)
Copyright (c) 2014 Armon Dadgar
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+ 37
- 0
pkg/net/mdns/README.md View File

@ -0,0 +1,37 @@
mdns
====
Simple mDNS client/server library in Golang. mDNS or Multicast DNS can be
used to discover services on the local network without the use of an authoritative
DNS server. This enables peer-to-peer discovery. It is important to note that many
networks restrict the use of multicasting, which prevents mDNS from functioning.
Notably, multicast cannot be used in any sort of cloud, or shared infrastructure
environment. However it works well in most office, home, or private infrastructure
environments.
Using the library is very simple, here is an example of publishing a service entry:
// Setup our service export
host, _ := os.Hostname()
info := []string{"My awesome service"},
service, _ := NewMDNSService(host, "_foobar._tcp", "", "", 8000, nil, info)
// Create the mDNS server, defer shutdown
server, _ := mdns.NewServer(&mdns.Config{Zone: service})
defer server.Shutdown()
Doing a lookup for service providers is also very simple:
// Make a channel for results and start listening
entriesCh := make(chan *mdns.ServiceEntry, 4)
go func() {
for entry := range entriesCh {
fmt.Printf("Got new entry: %v\n", entry)
}
}()
// Start the lookup
mdns.Lookup("_foobar._tcp", entriesCh)
close(entriesCh)

+ 347
- 0
pkg/net/mdns/client.go View File

@ -0,0 +1,347 @@
package mdns
import (
"fmt"
"net"
"strings"
"sync/atomic"
"time"
"github.com/miekg/dns"
"golang.org/x/net/ipv4"
"golang.org/x/net/ipv6"
)
// ServiceEntry is returned after we query for a service
type ServiceEntry struct {
Name string
Host string
AddrV4 net.IP
AddrV6 net.IP
Port int
Info string