Skip to content

Commit

Permalink
properly propagate HTTP errors, fixes #172
Browse files Browse the repository at this point in the history
  • Loading branch information
klizhentas committed Mar 8, 2016
1 parent 61411a5 commit 1eb952b
Show file tree
Hide file tree
Showing 12 changed files with 89 additions and 62 deletions.
5 changes: 1 addition & 4 deletions errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -320,10 +320,7 @@ type ConnectionProblemError struct {

// Error is debug - friendly error message
func (c *ConnectionProblemError) Error() string {
if c.Message != "" {
return c.Message
}
return "connection problem"
return fmt.Sprintf("connection problem: %v, %v", c.Message, c.Err.Error())
}

// IsConnectionProblemError indicates that this error is of ConnectionProblem
Expand Down
34 changes: 17 additions & 17 deletions lib/auth/auth_with_roles.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,21 +123,21 @@ func (a *AuthWithRoles) DeleteCertAuthority(id services.CertAuthID) error {
}
func (a *AuthWithRoles) GenerateToken(role teleport.Role, ttl time.Duration) (string, error) {
if err := a.permChecker.HasPermission(a.role, ActionGenerateToken); err != nil {
return "", err
return "", trace.Wrap(err)
} else {
return a.authServer.GenerateToken(role, ttl)
}
}
func (a *AuthWithRoles) RegisterUsingToken(token, hostID string, role teleport.Role) (keys PackedKeys, e error) {
if err := a.permChecker.HasPermission(a.role, ActionRegisterUsingToken); err != nil {
return PackedKeys{}, err
return PackedKeys{}, trace.Wrap(err)
} else {
return a.authServer.RegisterUsingToken(token, hostID, role)
}
}
func (a *AuthWithRoles) RegisterNewAuthServer(token string, publicSealKey encryptor.Key) (masterKey encryptor.Key, e error) {
if err := a.permChecker.HasPermission(a.role, ActionRegisterNewAuthServer); err != nil {
return encryptor.Key{}, err
return encryptor.Key{}, trace.Wrap(err)
} else {
return a.authServer.RegisterNewAuthServer(token, publicSealKey)
}
Expand Down Expand Up @@ -179,14 +179,14 @@ func (a *AuthWithRoles) GetSessionEvents(filter events.Filter) ([]session.Sessio
}
func (a *AuthWithRoles) GetChunkWriter(id string) (recorder.ChunkWriteCloser, error) {
if err := a.permChecker.HasPermission(a.role, ActionGetChunkWriter); err != nil {
return nil, err
return nil, trace.Wrap(err)
} else {
return a.recorder.GetChunkWriter(id)
}
}
func (a *AuthWithRoles) GetChunkReader(id string) (recorder.ChunkReadCloser, error) {
if err := a.permChecker.HasPermission(a.role, ActionGetChunkReader); err != nil {
return nil, err
return nil, trace.Wrap(err)
} else {
return a.recorder.GetChunkReader(id)
}
Expand All @@ -201,7 +201,7 @@ func (a *AuthWithRoles) UpsertServer(s services.Server, ttl time.Duration) error
}
func (a *AuthWithRoles) GetServers() ([]services.Server, error) {
if err := a.permChecker.HasPermission(a.role, ActionGetServers); err != nil {
return nil, err
return nil, trace.Wrap(err)
} else {
return a.authServer.GetServers()
}
Expand Down Expand Up @@ -229,14 +229,14 @@ func (a *AuthWithRoles) CheckPassword(user string, password []byte, hotpToken st
}
func (a *AuthWithRoles) SignIn(user string, password []byte) (*Session, error) {
if err := a.permChecker.HasPermission(a.role, ActionSignIn); err != nil {
return nil, err
return nil, trace.Wrap(err)
} else {
return a.authServer.SignIn(user, password)
}
}
func (a *AuthWithRoles) CreateWebSession(user string, prevSessionID string) (*Session, error) {
if err := a.permChecker.HasPermission(a.role, ActionCreateWebSession); err != nil {
return nil, err
return nil, trace.Wrap(err)
} else {
return a.authServer.CreateWebSession(user, prevSessionID)
}
Expand Down Expand Up @@ -264,7 +264,7 @@ func (a *AuthWithRoles) DeleteWebSession(user string, sid string) error {
}
func (a *AuthWithRoles) GetUsers() ([]services.User, error) {
if err := a.permChecker.HasPermission(a.role, ActionGetUsers); err != nil {
return nil, err
return nil, trace.Wrap(err)
} else {
return a.authServer.GetUsers()
}
Expand All @@ -278,7 +278,7 @@ func (a *AuthWithRoles) DeleteUser(user string) error {
}
func (a *AuthWithRoles) GenerateKeyPair(pass string) ([]byte, []byte, error) {
if err := a.permChecker.HasPermission(a.role, ActionGenerateKeyPair); err != nil {
return nil, nil, err
return nil, nil, trace.Wrap(err)
} else {
return a.authServer.GenerateKeyPair(pass)
}
Expand All @@ -288,29 +288,29 @@ func (a *AuthWithRoles) GenerateHostCert(
ttl time.Duration) ([]byte, error) {

if err := a.permChecker.HasPermission(a.role, ActionGenerateHostCert); err != nil {
return nil, err
return nil, trace.Wrap(err)
} else {
return a.authServer.GenerateHostCert(key, hostname, authDomain, role, ttl)
}
}
func (a *AuthWithRoles) GenerateUserCert(key []byte, user string, ttl time.Duration) ([]byte, error) {
if err := a.permChecker.HasPermission(a.role, ActionGenerateUserCert); err != nil {
return nil, err
return nil, trace.Wrap(err)
} else {
return a.authServer.GenerateUserCert(key, user, ttl)
}
}
func (a *AuthWithRoles) GetSealKeys() ([]encryptor.Key, error) {
if err := a.permChecker.HasPermission(a.role, ActionGetSealKeys); err != nil {
return nil, err
return nil, trace.Wrap(err)
} else {
return a.authServer.GetSealKeys()
}
}

func (a *AuthWithRoles) GenerateSealKey(keyName string) (encryptor.Key, error) {
if err := a.permChecker.HasPermission(a.role, ActionGenerateSealKey); err != nil {
return encryptor.Key{}, err
return encryptor.Key{}, trace.Wrap(err)
} else {
return a.authServer.GenerateSealKey(keyName)
}
Expand All @@ -334,15 +334,15 @@ func (a *AuthWithRoles) AddSealKey(key encryptor.Key) error {

func (a *AuthWithRoles) GetSealKey(keyID string) (encryptor.Key, error) {
if err := a.permChecker.HasPermission(a.role, ActionGetSealKey); err != nil {
return encryptor.Key{}, err
return encryptor.Key{}, trace.Wrap(err)
} else {
return a.authServer.GetSealKey(keyID)
}
}

func (a *AuthWithRoles) CreateSignupToken(user string, mappings []string) (token string, e error) {
if err := a.permChecker.HasPermission(a.role, ActionCreateSignupToken); err != nil {
return "", err
return "", trace.Wrap(err)
} else {
return a.authServer.CreateSignupToken(user, mappings)
}
Expand All @@ -351,7 +351,7 @@ func (a *AuthWithRoles) CreateSignupToken(user string, mappings []string) (token
func (a *AuthWithRoles) GetSignupTokenData(token string) (user string,
QRImg []byte, hotpFirstValues []string, e error) {
if err := a.permChecker.HasPermission(a.role, ActionGetSignupTokenData); err != nil {
return "", nil, nil, err
return "", nil, nil, trace.Wrap(err)
} else {
return a.authServer.GetSignupTokenData(token)
}
Expand Down
4 changes: 3 additions & 1 deletion lib/auth/new_web_user.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,9 @@ func (s *AuthServer) CreateSignupToken(user string, allowedLogins []string) (str
// check existing
_, err := s.GetPasswordHash(user)
if err == nil {
return "", trace.Errorf("login '%v' already exists", user)
return "", trace.Wrap(
teleport.BadParameter(
"user", fmt.Sprintf("user '%v' already exists", user)))
}

token, err := utils.CryptoRandomHex(WebSessionTokenLenBytes)
Expand Down
17 changes: 10 additions & 7 deletions lib/auth/tun.go
Original file line number Diff line number Diff line change
Expand Up @@ -493,7 +493,7 @@ type TunClient struct {

func NewTunClient(addr utils.NetAddr, user string, auth []ssh.AuthMethod) (*TunClient, error) {
if user == "" {
return nil, trace.Errorf("SSH connection requires a valid username")
return nil, trace.Wrap(teleport.BadParameter("user", "SSH connection requires a valid username"))
}
tc := &TunClient{
dialer: &TunDialer{auth: auth, addr: addr, user: user},
Expand All @@ -507,7 +507,7 @@ func NewTunClient(addr utils.NetAddr, user string, auth []ssh.AuthMethod) (*TunC
Transport: tr,
}))
if err != nil {
return nil, err
return nil, trace.Wrap(err)
}
tc.Client = *clt
tc.tr = tr
Expand Down Expand Up @@ -558,13 +558,13 @@ func (t *TunDialer) Close() error {
func (t *TunDialer) GetAgent() (AgentCloser, error) {
client, err := t.getClient() // we need an established connection first
if err != nil {
return nil, trace.Wrap(
teleport.ConnectionProblem("failed to connect to remote API", err))
return nil, trace.Wrap(err)
}
ch, _, err := client.OpenChannel(ReqWebSessionAgent, nil)
if err != nil {
return nil, trace.Wrap(
teleport.ConnectionProblem("failed to connect to remote API", err))
teleport.ConnectionProblem(
"failed to connect to remote API", err))
}
agentCloser := &tunAgent{client: client}
agentCloser.Agent = agent.NewClient(ch)
Expand All @@ -580,6 +580,10 @@ func (t *TunDialer) getClient() (*ssh.Client, error) {
log.Debugf("TunDialer.getClient(%v)", t.addr.String())
if err != nil {
log.Infof("TunDialer could not ssh.Dial: %v", err)
if utils.IsHandshakeFailedError(err) {
return nil, teleport.AccessDenied(
fmt.Sprintf("access denied to '%v': bad username or credentials", t.user))
}
return nil, trace.Wrap(err)
}
return client, nil
Expand Down Expand Up @@ -609,8 +613,7 @@ func (t *TunDialer) Dial(network, address string) (net.Conn, error) {
log.Debugf("TunDialer.Dial(%v, %v)", network, address)
client, err := t.getClient()
if err != nil {
return nil, trace.Wrap(
teleport.ConnectionProblem("failed to connect to remote API", err))
return nil, trace.Wrap(err)
}
conn, err := client.Dial(network, address)
if err != nil {
Expand Down
11 changes: 7 additions & 4 deletions lib/client/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,15 @@ import (
"syscall"
"time"

log "github.com/Sirupsen/logrus"

"github.com/gravitational/teleport"
"github.com/gravitational/teleport/lib/auth/native"
"github.com/gravitational/teleport/lib/defaults"
"github.com/gravitational/teleport/lib/services"
"github.com/gravitational/teleport/lib/utils"
"github.com/gravitational/teleport/lib/web"
"github.com/gravitational/trace"

log "github.com/Sirupsen/logrus"
"github.com/gravitational/trace"
"golang.org/x/crypto/ssh"
"golang.org/x/crypto/ssh/agent"
"golang.org/x/crypto/ssh/terminal"
Expand Down Expand Up @@ -162,7 +162,7 @@ func NewClient(c *Config) (tc *TeleportClient, err error) {
func (tc *TeleportClient) SSH(command string) (err error) {
// connecting via proxy?
if !tc.Config.ProxySpecified() {
return trace.Wrap(fmt.Errorf("proxy server is not specified"))
return trace.Wrap(teleport.BadParameter("server", "proxy server is not specified"))
}
proxyClient, err := tc.ConnectToProxy()
if err != nil {
Expand Down Expand Up @@ -453,6 +453,9 @@ func (tc *TeleportClient) makeHostKeyCallback() utils.HostKeyCallback {
err = tc.Login()
if err != nil {
log.Error(err)
// (TODO) klizhentas I don't know of any other way to
// pass this info to user
fmt.Println(err)
return trace.Wrap(err)
}
return CheckHostSignerFromCache(hostID, remote, key)
Expand Down
11 changes: 10 additions & 1 deletion lib/hangout/hangout.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,12 @@ func New(proxyTunnelAddress, nodeListeningAddress, authListeningAddress string,
if err != nil {
return nil, trace.Wrap(err)
}
cfg.Hostname = "localhost2"

cfg.HostUUID, err = utils.ReadOrMakeHostUUID(cfg.DataDir)
if err != nil {
return nil, trace.Wrap(err)
}
cfg.Hostname = cfg.HostUUID

cfg.Auth.KeysBackend.Type = "bolt"
cfg.Auth.KeysBackend.Params = `{"path": "` + cfg.DataDir + `/teleport.auth.db"}`
Expand Down Expand Up @@ -275,6 +280,10 @@ func (h *Hangout) initAuth(cfg service.Config, readOnlyHangout bool) error {
if err != nil {
return trace.Wrap(err)
}
cfg.HostUUID, err = utils.ReadOrMakeHostUUID(cfg.DataDir)
if err != nil {
return trace.Wrap(err)
}
acfg := auth.InitConfig{
Backend: b,
Authority: authority.New(),
Expand Down
4 changes: 4 additions & 0 deletions lib/httplib/httplib.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"fmt"
"io/ioutil"
"net/http"
"net/url"

"github.com/gravitational/teleport"

Expand Down Expand Up @@ -86,6 +87,9 @@ func ReplyError(w http.ResponseWriter, err error) {
// based on HTTP response code and HTTP body contents
func ConvertResponse(re *roundtrip.Response, err error) (*roundtrip.Response, error) {
if err != nil {
if uerr, ok := err.(*url.Error); ok && uerr != nil && uerr.Err != nil {
return nil, trace.Wrap(uerr.Err)
}
return nil, trace.Wrap(err)
}
switch re.Code() {
Expand Down
Loading

0 comments on commit 1eb952b

Please sign in to comment.