diff --git a/lib/auth/apiserver.go b/lib/auth/apiserver.go index bd943ab13c102..13126c9c64dca 100644 --- a/lib/auth/apiserver.go +++ b/lib/auth/apiserver.go @@ -150,9 +150,7 @@ func NewAPIServer(config *APIConfig) (http.Handler, error) { srv.DELETE("/:version/tunnelconnections/:cluster", srv.withAuth(srv.deleteTunnelConnections)) srv.DELETE("/:version/tunnelconnections", srv.withAuth(srv.deleteAllTunnelConnections)) - // Server Credentials - srv.POST("/:version/server/credentials", srv.withAuth(srv.generateHostCerts)) - + // Remote clusters srv.POST("/:version/remoteclusters", srv.withAuth(srv.createRemoteCluster)) srv.GET("/:version/remoteclusters/:cluster", srv.withAuth(srv.getRemoteCluster)) srv.GET("/:version/remoteclusters", srv.withAuth(srv.getRemoteClusters)) @@ -1031,6 +1029,9 @@ func (s *APIServer) registerUsingToken(auth ClientI, w http.ResponseWriter, r *h return nil, trace.Wrap(err) } + // Teleport 8 clients are still expecting the legacy JSON format. + // Teleport 9 clients handle both legacy and new. + // TODO(zmb3) return certs directly in Teleport 10 return LegacyCertsFromProto(certs), nil } @@ -1050,53 +1051,6 @@ func (s *APIServer) registerNewAuthServer(auth ClientI, w http.ResponseWriter, r return message("ok"), nil } -// DELETE IN 9.0 (zmb3) -type legacyHostCertsRequest struct { - HostID string `json:"host_id"` - NodeName string `json:"node_name"` - Roles types.SystemRoles `json:"roles"` - AdditionalPrincipals []string `json:"additional_principals,omitempty"` - DNSNames []string `json:"dns_names,omitempty"` - PublicTLSKey []byte `json:"public_tls_key"` - PublicSSHKey []byte `json:"public_ssh_key"` - RemoteAddr string `json:"remote_addr"` - Rotation *types.Rotation `json:"rotation,omitempty"` -} - -// DELETE IN 9.0 (zmb3) now available in GRPC server) -func (s *APIServer) generateHostCerts(auth ClientI, w http.ResponseWriter, r *http.Request, _ httprouter.Params, version string) (interface{}, error) { - // We can't use proto.HostCertsRequest here, because this old API expects - // a list of roles with exactly one element, rather than a single role. - var req legacyHostCertsRequest - if err := httplib.ReadJSON(r, &req); err != nil { - return nil, trace.Wrap(err) - } - - if len(req.Roles) != 1 { - return nil, trace.BadParameter("expected exactly one system role") - } - - // Pass along the remote address the request came from to the registration function. - req.RemoteAddr = r.RemoteAddr - - certs, err := auth.GenerateHostCerts(r.Context(), &proto.HostCertsRequest{ - HostID: req.HostID, - NodeName: req.NodeName, - Role: req.Roles[0], - AdditionalPrincipals: req.AdditionalPrincipals, - DNSNames: req.DNSNames, - PublicTLSKey: req.PublicTLSKey, - PublicSSHKey: req.PublicSSHKey, - RemoteAddr: req.RemoteAddr, - Rotation: req.Rotation, - }) - if err != nil { - return nil, trace.Wrap(err) - } - - return LegacyCertsFromProto(certs), nil -} - func (s *APIServer) rotateCertAuthority(auth ClientI, w http.ResponseWriter, r *http.Request, p httprouter.Params, version string) (interface{}, error) { var req RotateRequest if err := httplib.ReadJSON(r, &req); err != nil { diff --git a/lib/auth/clt.go b/lib/auth/clt.go index edf456d4ab0e4..7734c7269df77 100644 --- a/lib/auth/clt.go +++ b/lib/auth/clt.go @@ -552,6 +552,18 @@ func (c *Client) RegisterUsingToken(ctx context.Context, req *types.RegisterUsin return nil, trace.Wrap(err) } + var certs proto.Certs + if err := json.Unmarshal(out.Bytes(), &certs); err != nil { + return nil, trace.Wrap(err) + } + + // If we got certs, we're done, however, we may be talking to a Teleport 9 or earlier server, + // which still sends back the legacy JSON format. + if len(certs.SSH) > 0 && len(certs.TLS) > 0 { + return &certs, nil + } + + // DELETE IN 10.0.0 (zmb3) return UnmarshalLegacyCerts(out.Bytes()) } diff --git a/lib/auth/httpfallback.go b/lib/auth/httpfallback.go index 07e0bb8fe83a8..25414b18bc095 100644 --- a/lib/auth/httpfallback.go +++ b/lib/auth/httpfallback.go @@ -655,35 +655,6 @@ func (c *Client) ChangeUserAuthentication(ctx context.Context, req *proto.Change }, nil } -// GenerateHostCerts generates new host certificates (signed by the host CA). -// DELETE IN 9.0.0 (zmb3) -func (c *Client) GenerateHostCerts(ctx context.Context, req *proto.HostCertsRequest) (*proto.Certs, error) { - switch certs, err := c.APIClient.GenerateHostCerts(ctx, req); { - case err == nil: // GRPC version is available and succeeded - return certs, nil - case !trace.IsNotImplemented(err): // GRPC version available but failed - return nil, trace.Wrap(err) - } - - // fallback to legacy JSON API - out, err := c.PostJSON(c.Endpoint("server", "credentials"), legacyHostCertsRequest{ - HostID: req.HostID, - NodeName: req.NodeName, - Roles: types.SystemRoles{req.Role}, // old API requires a list of roles - AdditionalPrincipals: req.AdditionalPrincipals, - DNSNames: req.DNSNames, - PublicTLSKey: req.PublicTLSKey, - PublicSSHKey: req.PublicSSHKey, - RemoteAddr: req.RemoteAddr, - Rotation: req.Rotation, - }) - if err != nil { - return nil, trace.Wrap(err) - } - - return UnmarshalLegacyCerts(out.Bytes()) -} - // DELETE IN 9.0.0, to remove fallback and grpc call is already defined in api/client/client.go // // CreateAuthenticateChallenge creates and returns MFA challenges for a users registered MFA devices. diff --git a/lib/auth/register.go b/lib/auth/register.go index fc7619a9f0f47..2067ba76eccc1 100644 --- a/lib/auth/register.go +++ b/lib/auth/register.go @@ -532,7 +532,7 @@ type LegacyCerts struct { } // LegacyCertsFromProto converts proto.Certs to LegacyCerts. -// DELETE in 9.0.0 (Joerger/zmb3) +// DELETE in 10.0.0 (Joerger/zmb3) func LegacyCertsFromProto(c *proto.Certs) *LegacyCerts { return &LegacyCerts{ SSHCert: c.SSH, @@ -543,7 +543,7 @@ func LegacyCertsFromProto(c *proto.Certs) *LegacyCerts { } // UnmarshalLegacyCerts unmarshals the a legacy certs response as proto.Certs. -// DELETE in 9.0.0 (Joerger/zmb3) +// DELETE in 10.0.0 (Joerger/zmb3) func UnmarshalLegacyCerts(bytes []byte) (*proto.Certs, error) { var lc LegacyCerts if err := json.Unmarshal(bytes, &lc); err != nil { diff --git a/lib/client/weblogin.go b/lib/client/weblogin.go index 30bba0f53b351..5e41ffffd1be1 100644 --- a/lib/client/weblogin.go +++ b/lib/client/weblogin.go @@ -460,5 +460,17 @@ func HostCredentials(ctx context.Context, proxyAddr string, insecure bool, req t return nil, trace.Wrap(err) } + var certs proto.Certs + if err := json.Unmarshal(resp.Bytes(), &certs); err != nil { + return nil, trace.Wrap(err) + } + + // If we got certs, we're done, however, we may be talking to a Teleport 9 or earlier server, + // which still sends back the legacy JSON format. + if len(certs.SSH) > 0 && len(certs.TLS) > 0 { + return &certs, nil + } + + // DELETE IN 10.0.0 (zmb3) return auth.UnmarshalLegacyCerts(resp.Bytes()) } diff --git a/lib/web/apiserver.go b/lib/web/apiserver.go index a2138c931cae9..291cc746c8109 100644 --- a/lib/web/apiserver.go +++ b/lib/web/apiserver.go @@ -2341,6 +2341,9 @@ func (h *Handler) hostCredentials(w http.ResponseWriter, r *http.Request, p http return nil, trace.Wrap(err) } + // Teleport 8 clients are still expecting the legacy JSON format. + // Teleport 9 clients handle both legacy and new. + // TODO(zmb3) return certs directly in Teleport 10 return auth.LegacyCertsFromProto(certs), nil }