Skip to content

Commit

Permalink
Fix GenerateHostCerts http fallback with LegacyCerts. (gravitational#…
Browse files Browse the repository at this point in the history
…8469)

* Fix GenerateHostKeys http fallback with LegacyCerts (PackedKeys).

* Replace registerUsingTokenResponseJSON.

* Remove redundant fallback logic for pre v8 clusters.
  • Loading branch information
Joerger authored Oct 6, 2021
1 parent 16a5c33 commit 549b72c
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 43 deletions.
21 changes: 4 additions & 17 deletions lib/auth/apiserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -1024,15 +1024,6 @@ func (s *APIServer) generateToken(auth ClientI, w http.ResponseWriter, r *http.R
return token, nil
}

// registerUsingTokenResponseJSON is equivalent to proto.Certs, but
// uses JSON keys expected by old (7.x and earlier) clients
type registerUsingTokenResponseJSON struct {
SSHCert []byte `json:"cert"`
TLSCert []byte `json:"tls_cert"`
TLSCACerts [][]byte `json:"tls_ca_certs"`
SSHCACerts [][]byte `json:"ssh_ca_certs"`
}

func (s *APIServer) registerUsingToken(auth ClientI, w http.ResponseWriter, r *http.Request, _ httprouter.Params, version string) (interface{}, error) {
var req RegisterUsingTokenRequest
if err := httplib.ReadJSON(r, &req); err != nil {
Expand All @@ -1046,12 +1037,8 @@ func (s *APIServer) registerUsingToken(auth ClientI, w http.ResponseWriter, r *h
if err != nil {
return nil, trace.Wrap(err)
}
return &registerUsingTokenResponseJSON{
SSHCert: certs.SSH,
TLSCert: certs.TLS,
SSHCACerts: certs.SSHCACerts,
TLSCACerts: certs.TLSCACerts,
}, nil

return LegacyCertsFromProto(certs), nil
}

type registerNewAuthServerReq struct {
Expand Down Expand Up @@ -1099,7 +1086,7 @@ func (s *APIServer) generateHostCerts(auth ClientI, w http.ResponseWriter, r *ht
// Pass along the remote address the request came from to the registration function.
req.RemoteAddr = r.RemoteAddr

keys, err := auth.GenerateHostCerts(r.Context(), &proto.HostCertsRequest{
certs, err := auth.GenerateHostCerts(r.Context(), &proto.HostCertsRequest{
HostID: req.HostID,
NodeName: req.NodeName,
Role: req.Roles[0],
Expand All @@ -1114,7 +1101,7 @@ func (s *APIServer) generateHostCerts(auth ClientI, w http.ResponseWriter, r *ht
return nil, trace.Wrap(err)
}

return keys, nil
return LegacyCertsFromProto(certs), nil
}

func (s *APIServer) rotateCertAuthority(auth ClientI, w http.ResponseWriter, r *http.Request, p httprouter.Params, version string) (interface{}, error) {
Expand Down
11 changes: 1 addition & 10 deletions lib/auth/clt.go
Original file line number Diff line number Diff line change
Expand Up @@ -543,17 +543,8 @@ func (c *Client) RegisterUsingToken(req RegisterUsingTokenRequest) (*proto.Certs
if err != nil {
return nil, trace.Wrap(err)
}
var response registerUsingTokenResponseJSON
if err := json.Unmarshal(out.Bytes(), &response); err != nil {
return nil, trace.Wrap(err)
}

return &proto.Certs{
SSH: response.SSHCert,
TLS: response.TLSCert,
SSHCACerts: response.SSHCACerts,
TLSCACerts: response.TLSCACerts,
}, nil
return UnmarshalLegacyCerts(out.Bytes())
}

// RegisterNewAuthServer is used to register new auth server with token
Expand Down
6 changes: 1 addition & 5 deletions lib/auth/httpfallback.go
Original file line number Diff line number Diff line change
Expand Up @@ -704,12 +704,8 @@ func (c *Client) GenerateHostCerts(ctx context.Context, req *proto.HostCertsRequ
if err != nil {
return nil, trace.Wrap(err)
}
var certs proto.Certs
if err := json.Unmarshal(out.Bytes(), &certs); err != nil {
return nil, trace.Wrap(err)
}

return &certs, nil
return UnmarshalLegacyCerts(out.Bytes())
}

// DELETE IN 9.0.0, to remove fallback and grpc call is already defined in api/client/client.go
Expand Down
37 changes: 37 additions & 0 deletions lib/auth/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package auth
import (
"context"
"crypto/x509"
"encoding/json"

"github.com/gravitational/teleport"
"github.com/gravitational/teleport/api/client"
Expand Down Expand Up @@ -414,3 +415,39 @@ func ReRegister(params ReRegisterParams) (*Identity, error) {

return ReadIdentityFromKeyPair(params.PrivateKey, certs)
}

// LegacyCerts is equivalent to proto.Certs, but uses
// JSON keys expected by old clients (7.x and earlier)
// DELETE in 9.0.0 (Joerger/zmb3)
type LegacyCerts struct {
SSHCert []byte `json:"cert"`
TLSCert []byte `json:"tls_cert"`
TLSCACerts [][]byte `json:"tls_ca_certs"`
SSHCACerts [][]byte `json:"ssh_ca_certs"`
}

// LegacyCertsFromProto converts proto.Certs to LegacyCerts.
// DELETE in 9.0.0 (Joerger/zmb3)
func LegacyCertsFromProto(c *proto.Certs) *LegacyCerts {
return &LegacyCerts{
SSHCert: c.SSH,
TLSCert: c.TLS,
SSHCACerts: c.SSHCACerts,
TLSCACerts: c.TLSCACerts,
}
}

// UnmarshalLegacyCerts unmarshals the a legacy certs response as proto.Certs.
// DELETE in 9.0.0 (Joerger/zmb3)
func UnmarshalLegacyCerts(bytes []byte) (*proto.Certs, error) {
var lc LegacyCerts
if err := json.Unmarshal(bytes, &lc); err != nil {
return nil, trace.Wrap(err)
}
return &proto.Certs{
SSH: lc.SSHCert,
TLS: lc.TLSCert,
TLSCACerts: lc.TLSCACerts,
SSHCACerts: lc.SSHCACerts,
}, nil
}
8 changes: 1 addition & 7 deletions lib/client/weblogin.go
Original file line number Diff line number Diff line change
Expand Up @@ -459,11 +459,5 @@ func HostCredentials(ctx context.Context, proxyAddr string, insecure bool, req a
return nil, trace.Wrap(err)
}

var certs *proto.Certs
err = json.Unmarshal(resp.Bytes(), &certs)
if err != nil {
return nil, trace.Wrap(err)
}

return certs, nil
return auth.UnmarshalLegacyCerts(resp.Bytes())
}
3 changes: 1 addition & 2 deletions lib/client/weblogin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import (
"net/http/httptest"
"testing"

"github.com/gravitational/teleport/api/client/proto"
"github.com/gravitational/teleport/lib/auth"
"github.com/stretchr/testify/require"
)
Expand All @@ -46,7 +45,7 @@ func TestPlainHttpFallback(t *testing.T) {
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(proto.Certs{})
json.NewEncoder(w).Encode(auth.LegacyCerts{})
},
actionUnderTest: func(ctx context.Context, addr string, insecure bool) error {
_, err := HostCredentials(ctx, addr, insecure, auth.RegisterUsingTokenRequest{})
Expand Down
4 changes: 2 additions & 2 deletions lib/web/apiserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -2281,12 +2281,12 @@ func (h *Handler) hostCredentials(w http.ResponseWriter, r *http.Request, p http
}

authClient := h.cfg.ProxyClient
packedKeys, err := authClient.RegisterUsingToken(req)
certs, err := authClient.RegisterUsingToken(req)
if err != nil {
return nil, trace.Wrap(err)
}

return packedKeys, nil
return auth.LegacyCertsFromProto(certs), nil
}

// createSSHCert is a web call that generates new SSH certificate based
Expand Down

0 comments on commit 549b72c

Please sign in to comment.