Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Read join tokens from file, fixes #2515. #2864

Merged
merged 1 commit into from
Jul 17, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 1 addition & 16 deletions lib/auth/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ package auth
import (
"context"
"crypto/x509"
"io/ioutil"
"strings"

"github.com/gravitational/teleport"
"github.com/gravitational/teleport/lib"
Expand Down Expand Up @@ -106,7 +104,7 @@ type HostCredentials func(context.Context, string, bool, RegisterUsingTokenReque
func Register(params RegisterParams) (*Identity, error) {
// Read in the token. The token can either be passed in or come from a file
// on disk.
token, err := readToken(params.Token)
token, err := utils.ReadToken(params.Token)
if err != nil {
return nil, trace.Wrap(err)
}
Expand Down Expand Up @@ -351,19 +349,6 @@ func ReRegister(params ReRegisterParams) (*Identity, error) {
return ReadIdentityFromKeyPair(keys)
}

func readToken(token string) (string, error) {
if !strings.HasPrefix(token, "/") {
return token, nil
}
// treat it as a file
out, err := ioutil.ReadFile(token)
if err != nil {
return "", nil
}
// trim newlines as tokens in files tend to have newlines
return strings.TrimSpace(string(out)), nil
}

// PackedKeys is a collection of private key, SSH host certificate
// and TLS certificate and certificate authority issued the certificate
type PackedKeys struct {
Expand Down
8 changes: 6 additions & 2 deletions lib/config/configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,9 @@ func ApplyFileConfig(fc *FileConfig, cfg *service.Config) error {
cfg.AuthServers = append(cfg.AuthServers, *addr)
}
}
cfg.ApplyToken(fc.AuthToken)
if _, err := cfg.ApplyToken(fc.AuthToken); err != nil {
return trace.Wrap(err)
}

if fc.Global.DataDir != "" {
cfg.DataDir = fc.Global.DataDir
Expand Down Expand Up @@ -909,7 +911,9 @@ func Configure(clf *CommandLineFlags, cfg *service.Config) error {
}

// apply --token flag:
cfg.ApplyToken(clf.AuthToken)
if _, err := cfg.ApplyToken(clf.AuthToken); err != nil {
return trace.Wrap(err)
}

// Apply flags used for the node to validate the Auth Server.
if clf.CAPin != "" {
Expand Down
8 changes: 7 additions & 1 deletion lib/config/configuration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -367,14 +367,20 @@ teleport:
}

func (s *ConfigTestSuite) TestApplyConfig(c *check.C) {
conf, err := ReadConfig(bytes.NewBufferString(SmallConfigString))
tokenPath := filepath.Join(s.tempDir, "small-config-token")
err := ioutil.WriteFile(tokenPath, []byte("join-token"), 0644)
c.Assert(err, check.IsNil)

conf, err := ReadConfig(bytes.NewBufferString(fmt.Sprintf(SmallConfigString, tokenPath)))
c.Assert(err, check.IsNil)
c.Assert(conf, check.NotNil)
c.Assert(conf.Proxy.PublicAddr, check.DeepEquals, utils.Strings{"web3:443"})

cfg := service.MakeDefaultConfig()
err = ApplyFileConfig(conf, cfg)
c.Assert(err, check.IsNil)

c.Assert(cfg.Token, check.Equals, "join-token")
c.Assert(cfg.Auth.StaticTokens.GetStaticTokens(), check.DeepEquals, services.ProvisionTokensFromV1([]services.ProvisionTokenV1{
{
Token: "xxx",
Expand Down
2 changes: 1 addition & 1 deletion lib/config/testdata_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,10 @@ teleport:
nodename: cat.example.com
advertise_ip: 10.10.10.1
pid_file: /var/run/teleport.pid
auth_token: %v
auth_servers:
- auth0.server.example.org:3024
- auth1.server.example.org:3024
auth_token: xxxyyy
log:
output: stderr
severity: INFO
Expand Down
18 changes: 13 additions & 5 deletions lib/service/cfg.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import (
"github.com/gravitational/teleport/lib/utils"

"github.com/ghodss/yaml"
"github.com/gravitational/trace"
"github.com/jonboulle/clockwork"
)

Expand Down Expand Up @@ -176,13 +177,20 @@ type Config struct {
// ApplyToken assigns a given token to all internal services but only if token
// is not an empty string.
//
// Returns 'true' if token was modified
func (cfg *Config) ApplyToken(token string) bool {
// returns:
// true, nil if the token has been modified
// false, nil if the token has not been modified
// false, err if there was an error
func (cfg *Config) ApplyToken(token string) (bool, error) {
if token != "" {
cfg.Token = token
return true
var err error
cfg.Token, err = utils.ReadToken(token)
if err != nil {
return false, trace.Wrap(err)
}
return true, nil
}
return false
return false, nil
}

// RoleConfig is a config for particular Teleport role
Expand Down
40 changes: 40 additions & 0 deletions lib/utils/token.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
Copyright 2019 Gravitational, Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package utils

import (
"io/ioutil"
"strings"

"github.com/gravitational/trace"
)

// ReadToken is a utility function to read the token
// from the disk if it looks like a path,
// otherwise, treat it as a value
func ReadToken(token string) (string, error) {
if !strings.HasPrefix(token, "/") {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we support relative paths for the other config values? If so, might be nice to support both "/" and "./".

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we don't support relative paths yet I think, and probably a good thing as we will avoid ambiguity here

return token, nil
}
// treat it as a file
out, err := ioutil.ReadFile(token)
if err != nil {
return "", trace.ConvertSystemError(err)
}
// trim newlines as tokens in files tend to have newlines
return strings.TrimSpace(string(out)), nil
}
19 changes: 19 additions & 0 deletions lib/utils/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -461,3 +461,22 @@ func (s *UtilsSuite) TestMarshalYAML(c *check.C) {
}
}
}

// TestReadToken tests reading token from file and as is
func (s *UtilsSuite) TestReadToken(c *check.C) {
tok, err := ReadToken("token")
c.Assert(tok, check.Equals, "token")
c.Assert(err, check.IsNil)

_, err = ReadToken("/tmp/non-existent-token-for-teleport-tests-not-found")
fixtures.ExpectNotFound(c, err)

dir := c.MkDir()
tokenPath := filepath.Join(dir, "token")
err = ioutil.WriteFile(tokenPath, []byte("shmoken"), 0644)
c.Assert(err, check.IsNil)

tok, err = ReadToken(tokenPath)
c.Assert(err, check.IsNil)
c.Assert(tok, check.Equals, "shmoken")
}