diff --git a/api/client/joinservice.go b/api/client/joinservice.go index 71db117b4acf..0e46ec5bacf4 100644 --- a/api/client/joinservice.go +++ b/api/client/joinservice.go @@ -22,6 +22,7 @@ import ( "github.com/gravitational/trace" "github.com/gravitational/teleport/api/client/proto" + "github.com/gravitational/teleport/api/types" ) // JoinServiceClient is a client for the JoinService, which runs on both the @@ -200,3 +201,13 @@ func (c *JoinServiceClient) RegisterUsingTPMMethod( return certs, nil } + +// RegisterUsingToken registers the caller using a token and returns signed +// certs. +// This is used where a more specific RPC has not been introduced for the join +// method. +func (c *JoinServiceClient) RegisterUsingToken( + ctx context.Context, req *types.RegisterUsingTokenRequest, +) (*proto.Certs, error) { + return c.grpcClient.RegisterUsingToken(ctx, req) +} diff --git a/api/client/proto/joinservice.pb.go b/api/client/proto/joinservice.pb.go index 78690405a47e..d8d425c87a89 100644 --- a/api/client/proto/joinservice.pb.go +++ b/api/client/proto/joinservice.pb.go @@ -794,56 +794,57 @@ func init() { } var fileDescriptor_d7e760ce923b836e = []byte{ - // 783 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x55, 0xc1, 0x6e, 0xdb, 0x46, - 0x10, 0x15, 0x5d, 0x5b, 0xae, 0x47, 0x6a, 0x6b, 0x2d, 0x0a, 0x57, 0x16, 0x6c, 0x59, 0x66, 0xdd, - 0x5a, 0x45, 0x51, 0xc9, 0x50, 0x7f, 0xa0, 0x92, 0x6a, 0x40, 0x6e, 0xe3, 0xc0, 0xa0, 0x9d, 0x43, - 0x72, 0x21, 0x56, 0xd4, 0x40, 0xde, 0x88, 0x26, 0x99, 0xdd, 0x95, 0x01, 0xe5, 0x67, 0xf2, 0x05, - 0xb9, 0xe5, 0x23, 0x72, 0x08, 0x82, 0x1c, 0xf2, 0x01, 0x81, 0xff, 0x21, 0xf7, 0x80, 0xbb, 0x4b, - 0x89, 0xa2, 0x25, 0x3b, 0x01, 0x82, 0x5c, 0x48, 0xec, 0xcc, 0xdb, 0x99, 0x79, 0x6f, 0x66, 0x77, - 0xa1, 0x21, 0xd1, 0xc7, 0x28, 0xe4, 0xb2, 0xe9, 0xe3, 0x90, 0x7a, 0x93, 0xa6, 0xe7, 0x33, 0x0c, - 0x64, 0x33, 0xe2, 0xa1, 0x0c, 0x9b, 0x4f, 0x43, 0x16, 0x08, 0xe4, 0xd7, 0xcc, 0xc3, 0x86, 0xb2, - 0x90, 0x35, 0xf5, 0xab, 0xd4, 0xef, 0xdc, 0xe6, 0x21, 0x97, 0x42, 0x6f, 0xa8, 0xec, 0x67, 0x91, - 0x72, 0x12, 0xa1, 0xd0, 0x5f, 0x0d, 0xb1, 0x5f, 0x59, 0xb0, 0xeb, 0xe0, 0x90, 0x09, 0x89, 0xfc, - 0x91, 0x60, 0xc1, 0xf0, 0xa4, 0x7d, 0x7a, 0x8a, 0xf2, 0x32, 0x1c, 0x38, 0xf8, 0x6c, 0x8c, 0x42, - 0x12, 0x0a, 0x3b, 0xdc, 0x00, 0xdc, 0x71, 0x8c, 0x70, 0x65, 0x38, 0xc2, 0xc0, 0xe5, 0xda, 0x5f, - 0xb6, 0x6a, 0x56, 0xbd, 0xd0, 0xaa, 0x35, 0x74, 0xd4, 0xb9, 0x58, 0x17, 0x31, 0xd0, 0xc4, 0x71, - 0xb6, 0xf9, 0x32, 0x17, 0x39, 0x82, 0x9f, 0x85, 0x14, 0x2e, 0x1b, 0x60, 0x20, 0x99, 0x9c, 0x4c, - 0x43, 0xaf, 0xd4, 0xac, 0x7a, 0xd1, 0x21, 0x42, 0x8a, 0x13, 0xe3, 0x32, 0x3b, 0xec, 0x3e, 0x54, - 0x97, 0x55, 0x2d, 0xa2, 0x30, 0x10, 0x48, 0x76, 0x60, 0xc3, 0xbb, 0xa4, 0xbe, 0x8f, 0xc1, 0x10, - 0x55, 0x8d, 0x1b, 0xce, 0xcc, 0x40, 0x6c, 0x58, 0x53, 0x42, 0xa9, 0x14, 0x85, 0x56, 0x51, 0xab, - 0xd1, 0xe8, 0xc6, 0x36, 0x47, 0xbb, 0xec, 0x37, 0x16, 0xec, 0xcd, 0x25, 0x69, 0x3f, 0x1f, 0x73, - 0xfc, 0xe6, 0xe2, 0xfc, 0x0a, 0x3f, 0x50, 0x29, 0x51, 0x48, 0x1c, 0xb8, 0x03, 0x2a, 0xa9, 0x51, - 0xa5, 0x98, 0x18, 0xff, 0xa5, 0x92, 0x92, 0x7d, 0x28, 0x52, 0xcf, 0x43, 0x21, 0x74, 0xfe, 0xf2, - 0x77, 0x8a, 0x70, 0x41, 0xdb, 0x54, 0x38, 0x7b, 0x00, 0xb5, 0xe5, 0x6c, 0xbe, 0x9a, 0x68, 0xc7, - 0x70, 0x38, 0xcf, 0xf2, 0xcc, 0x34, 0xa6, 0x9b, 0x84, 0x99, 0x26, 0xab, 0xc0, 0xf7, 0x22, 0xf4, - 0xc7, 0x92, 0x85, 0x81, 0xca, 0x55, 0x74, 0xa6, 0x6b, 0xfb, 0xa3, 0x05, 0x07, 0x8b, 0xe3, 0x9c, - 0x04, 0x4c, 0x32, 0xea, 0x27, 0xea, 0x74, 0xa1, 0x18, 0x1f, 0x94, 0x2f, 0x16, 0xbc, 0x10, 0xef, - 0x4a, 0x82, 0x6c, 0xc3, 0x3a, 0x8e, 0xdc, 0x98, 0x80, 0x16, 0xb7, 0x97, 0x73, 0xf2, 0x38, 0x8a, - 0x79, 0x91, 0x5f, 0x20, 0x8f, 0x23, 0x77, 0x84, 0x13, 0x25, 0x69, 0xec, 0x59, 0xc3, 0xd1, 0xff, - 0x38, 0x21, 0x0f, 0x81, 0xe8, 0x0e, 0xd0, 0xb8, 0x60, 0x37, 0xa2, 0x9c, 0x5e, 0x89, 0xf2, 0xaa, - 0x4a, 0xbf, 0x67, 0x94, 0xb9, 0x38, 0x3b, 0x6d, 0xcf, 0x30, 0x67, 0x31, 0x04, 0x25, 0x72, 0xe1, - 0x94, 0x68, 0xc6, 0x2c, 0x3a, 0xab, 0xb0, 0x82, 0x23, 0xfb, 0x6d, 0xf6, 0x38, 0x4e, 0x79, 0x27, - 0xb5, 0xb6, 0x61, 0x95, 0x05, 0x2c, 0x21, 0xfa, 0xa7, 0xc9, 0xf4, 0x39, 0x5a, 0xf5, 0x72, 0x8e, - 0xda, 0x4a, 0x5c, 0x20, 0xd3, 0xa6, 0xba, 0xdc, 0xb4, 0xc3, 0x34, 0xb5, 0x71, 0x67, 0xc0, 0x5b, - 0x4d, 0xec, 0xe5, 0x9c, 0x92, 0x97, 0x35, 0x76, 0x36, 0x60, 0x3d, 0xa2, 0x13, 0x3f, 0xa4, 0x03, - 0xfb, 0x85, 0x95, 0x39, 0xa9, 0x29, 0x42, 0x66, 0x0e, 0x1e, 0x40, 0x29, 0x5d, 0x4e, 0xba, 0x8f, - 0xbb, 0x33, 0x21, 0x8f, 0x03, 0x8f, 0x4f, 0x22, 0x89, 0x83, 0x2e, 0x47, 0x75, 0x19, 0x50, 0xbf, - 0x97, 0x73, 0x36, 0x53, 0xc9, 0xb5, 0x3e, 0x07, 0x77, 0x0c, 0x69, 0xdc, 0x3d, 0xe5, 0x4c, 0x57, - 0xf8, 0xd2, 0x82, 0xf2, 0xb2, 0x46, 0x91, 0x2d, 0xc8, 0x47, 0xe3, 0xbe, 0xcf, 0x3c, 0x33, 0xa1, - 0x66, 0x45, 0xf6, 0xa0, 0xe0, 0x71, 0xa4, 0x12, 0xd3, 0x47, 0x12, 0xb4, 0x49, 0x1d, 0xc8, 0xbf, - 0x80, 0x18, 0x40, 0xaa, 0xd5, 0x7a, 0x86, 0x9c, 0x92, 0xf6, 0xa4, 0x32, 0x92, 0x3f, 0x60, 0xd3, - 0xc0, 0x05, 0x1b, 0x06, 0x54, 0x8e, 0x39, 0xaa, 0x59, 0x2a, 0x3a, 0x3f, 0x69, 0xfb, 0x79, 0x62, - 0xb6, 0x1f, 0xc3, 0xd6, 0x62, 0x39, 0xc8, 0x21, 0xc4, 0x60, 0xb3, 0x72, 0xfb, 0x7e, 0xd8, 0x37, - 0x55, 0xff, 0x38, 0x33, 0x77, 0xfc, 0xb0, 0x1f, 0xb3, 0x12, 0xe8, 0x71, 0x4c, 0x6e, 0x58, 0xb3, - 0x6a, 0xbd, 0x5f, 0x81, 0xc2, 0x7f, 0x21, 0x0b, 0xce, 0xf5, 0xb3, 0x43, 0x18, 0x6c, 0x2d, 0xbe, - 0x65, 0xc9, 0xc1, 0xa2, 0x31, 0xc9, 0x3e, 0x1d, 0x95, 0xdf, 0xee, 0x41, 0xe9, 0x01, 0xa8, 0x5b, - 0x47, 0x16, 0x09, 0xa1, 0xbc, 0xec, 0x76, 0x22, 0xbf, 0x2f, 0x0a, 0x73, 0xfb, 0x32, 0xae, 0x1c, - 0xde, 0x8b, 0x4b, 0x25, 0xcc, 0x72, 0x9b, 0xce, 0xe5, 0x62, 0x6e, 0xd9, 0x73, 0xb8, 0x98, 0xdb, - 0xad, 0xe1, 0x8e, 0x53, 0x75, 0xfe, 0x79, 0x7d, 0x53, 0xb5, 0xde, 0xdd, 0x54, 0xad, 0x0f, 0x37, - 0x55, 0xeb, 0x49, 0x6b, 0xc8, 0xe4, 0xe5, 0xb8, 0xdf, 0xf0, 0xc2, 0xab, 0xe6, 0x90, 0xd3, 0x6b, - 0xa6, 0x47, 0x80, 0xfa, 0xcd, 0xe9, 0x6b, 0x4d, 0x23, 0x36, 0xf7, 0xa8, 0xf7, 0xf3, 0xea, 0xf7, - 0xf7, 0xa7, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfa, 0x5a, 0x2e, 0x2f, 0x32, 0x08, 0x00, 0x00, + // 795 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x56, 0xcd, 0x6e, 0x22, 0x47, + 0x10, 0x66, 0xfc, 0x83, 0xe3, 0x82, 0x24, 0xa6, 0x15, 0x39, 0x18, 0xd9, 0x18, 0x4f, 0x9c, 0x98, + 0x28, 0x0a, 0x58, 0xe4, 0x05, 0x02, 0xd8, 0x12, 0x4e, 0xe2, 0xc8, 0x1a, 0x3b, 0x87, 0xe4, 0x32, + 0x6a, 0x86, 0x12, 0xee, 0x30, 0x9e, 0x99, 0x74, 0x37, 0x96, 0xc8, 0xa3, 0xe4, 0x92, 0x27, 0xd8, + 0xdb, 0x3e, 0xc4, 0x1e, 0x56, 0xab, 0x7d, 0x84, 0x95, 0xdf, 0x61, 0xef, 0xab, 0xe9, 0xee, 0x81, + 0x61, 0x00, 0x7b, 0x57, 0x5a, 0xed, 0x85, 0x51, 0x57, 0x55, 0x57, 0xd5, 0xf7, 0xd5, 0x4f, 0x03, + 0x0d, 0x89, 0x3e, 0x46, 0x21, 0x97, 0x4d, 0x1f, 0x87, 0xd4, 0x9b, 0x34, 0x3d, 0x9f, 0x61, 0x20, + 0x9b, 0x11, 0x0f, 0x65, 0xd8, 0xfc, 0x3b, 0x64, 0x81, 0x40, 0x7e, 0xcf, 0x3c, 0x6c, 0x28, 0x09, + 0xd9, 0x54, 0x9f, 0x4a, 0xfd, 0xd1, 0x6b, 0x1e, 0x72, 0x29, 0xf4, 0x85, 0xca, 0x51, 0xd6, 0x52, + 0x4e, 0x22, 0x14, 0xfa, 0x57, 0x9b, 0xd8, 0xcf, 0x2d, 0x38, 0x70, 0x70, 0xc8, 0x84, 0x44, 0xfe, + 0x87, 0x60, 0xc1, 0xf0, 0xa2, 0x7d, 0x79, 0x89, 0xf2, 0x36, 0x1c, 0x38, 0xf8, 0xcf, 0x18, 0x85, + 0x24, 0x14, 0xf6, 0xb9, 0x31, 0x70, 0xc7, 0xb1, 0x85, 0x2b, 0xc3, 0x11, 0x06, 0x2e, 0xd7, 0xfa, + 0xb2, 0x55, 0xb3, 0xea, 0x85, 0x56, 0xad, 0xa1, 0xbd, 0xce, 0xf9, 0xba, 0x89, 0x0d, 0x8d, 0x1f, + 0x67, 0x8f, 0xaf, 0x52, 0x91, 0x53, 0xf8, 0x4a, 0x48, 0xe1, 0xb2, 0x01, 0x06, 0x92, 0xc9, 0xc9, + 0xd4, 0xf5, 0x5a, 0xcd, 0xaa, 0x17, 0x1d, 0x22, 0xa4, 0xb8, 0x30, 0x2a, 0x73, 0xc3, 0xee, 0x43, + 0x75, 0x55, 0xd6, 0x22, 0x0a, 0x03, 0x81, 0x64, 0x1f, 0xb6, 0xbd, 0x5b, 0xea, 0xfb, 0x18, 0x0c, + 0x51, 0xe5, 0xb8, 0xed, 0xcc, 0x04, 0xc4, 0x86, 0x4d, 0x45, 0x94, 0x0a, 0x51, 0x68, 0x15, 0x35, + 0x1b, 0x8d, 0x6e, 0x2c, 0x73, 0xb4, 0xca, 0x7e, 0x69, 0xc1, 0xe1, 0x5c, 0x90, 0xf6, 0xbf, 0x63, + 0x8e, 0x9f, 0x9c, 0x9c, 0x6f, 0xe0, 0x73, 0x2a, 0x25, 0x0a, 0x89, 0x03, 0x77, 0x40, 0x25, 0x35, + 0xac, 0x14, 0x13, 0xe1, 0x19, 0x95, 0x94, 0x1c, 0x41, 0x91, 0x7a, 0x1e, 0x0a, 0xa1, 0xe3, 0x97, + 0xd7, 0x15, 0xe0, 0x82, 0x96, 0x29, 0x77, 0xf6, 0x00, 0x6a, 0xab, 0xd1, 0x7c, 0x34, 0xd2, 0xce, + 0xe1, 0x64, 0x1e, 0xe5, 0x95, 0x29, 0x4c, 0x37, 0x71, 0x33, 0x0d, 0x56, 0x81, 0xcf, 0x44, 0xe8, + 0x8f, 0x25, 0x0b, 0x03, 0x15, 0xab, 0xe8, 0x4c, 0xcf, 0xf6, 0x5b, 0x0b, 0x8e, 0x97, 0xfb, 0xb9, + 0x08, 0x98, 0x64, 0xd4, 0x4f, 0xd8, 0xe9, 0x42, 0x31, 0x1e, 0x94, 0x0f, 0x26, 0xbc, 0x10, 0xdf, + 0x4a, 0x9c, 0xec, 0xc1, 0x16, 0x8e, 0xdc, 0x18, 0x80, 0x26, 0xb7, 0x97, 0x73, 0xf2, 0x38, 0x8a, + 0x71, 0x91, 0xaf, 0x21, 0x8f, 0x23, 0x77, 0x84, 0x13, 0x45, 0x69, 0xac, 0xd9, 0xc4, 0xd1, 0xaf, + 0x38, 0x21, 0xbf, 0x03, 0xd1, 0x15, 0xa0, 0x71, 0xc2, 0x6e, 0x44, 0x39, 0xbd, 0x13, 0xe5, 0x0d, + 0x15, 0xfe, 0xd0, 0x30, 0x73, 0x73, 0x75, 0xd9, 0x9e, 0xd9, 0x5c, 0xc5, 0x26, 0x28, 0x91, 0x0b, + 0xa7, 0x44, 0x33, 0x62, 0xd1, 0xd9, 0x80, 0x35, 0x1c, 0xd9, 0xaf, 0xb2, 0xe3, 0x38, 0xc5, 0x9d, + 0xe4, 0xda, 0x86, 0x0d, 0x16, 0xb0, 0x04, 0xe8, 0x0f, 0x26, 0xd2, 0xfb, 0x70, 0xd5, 0xcb, 0x39, + 0xea, 0x2a, 0x71, 0x81, 0x4c, 0x8b, 0xea, 0x72, 0x53, 0x0e, 0x53, 0xd4, 0xc6, 0xa3, 0x0e, 0x17, + 0x8a, 0xd8, 0xcb, 0x39, 0x25, 0x2f, 0x2b, 0xec, 0x6c, 0xc3, 0x56, 0x44, 0x27, 0x7e, 0x48, 0x07, + 0xf6, 0xff, 0x56, 0x66, 0x52, 0x53, 0x80, 0x4c, 0x1f, 0xfc, 0x06, 0xa5, 0x74, 0x3a, 0xe9, 0x3a, + 0x1e, 0xcc, 0x88, 0x3c, 0x0f, 0x3c, 0x3e, 0x89, 0x24, 0x0e, 0xba, 0x1c, 0xd5, 0x32, 0xa0, 0x7e, + 0x2f, 0xe7, 0xec, 0xa4, 0x82, 0x6b, 0x7e, 0x8e, 0x1f, 0x69, 0xd2, 0xb8, 0x7a, 0x4a, 0x99, 0xce, + 0xf0, 0x99, 0x05, 0xe5, 0x55, 0x85, 0x22, 0xbb, 0x90, 0x8f, 0xc6, 0x7d, 0x9f, 0x79, 0xa6, 0x43, + 0xcd, 0x89, 0x1c, 0x42, 0xc1, 0xe3, 0x48, 0x25, 0xa6, 0x47, 0x12, 0xb4, 0x48, 0x0d, 0xe4, 0x8f, + 0x40, 0x8c, 0x41, 0xaa, 0xd4, 0xba, 0x87, 0x9c, 0x92, 0xd6, 0xa4, 0x22, 0x92, 0xef, 0x61, 0xc7, + 0x98, 0x0b, 0x36, 0x0c, 0xa8, 0x1c, 0x73, 0x54, 0xbd, 0x54, 0x74, 0xbe, 0xd4, 0xf2, 0xeb, 0x44, + 0x6c, 0xff, 0x09, 0xbb, 0xcb, 0xe9, 0x20, 0x27, 0x10, 0x1b, 0x9b, 0x93, 0xdb, 0xf7, 0xc3, 0xbe, + 0xc9, 0xfa, 0x8b, 0x99, 0xb8, 0xe3, 0x87, 0xfd, 0x18, 0x95, 0x40, 0x8f, 0x63, 0xb2, 0x61, 0xcd, + 0xa9, 0xf5, 0xdf, 0x3a, 0x14, 0x7e, 0x09, 0x59, 0x70, 0xad, 0x9f, 0x1d, 0xc2, 0x60, 0x77, 0xf9, + 0x96, 0x25, 0xc7, 0xcb, 0xda, 0x24, 0xfb, 0x74, 0x54, 0xbe, 0x7d, 0xc2, 0x4a, 0x37, 0x40, 0xdd, + 0x3a, 0xb5, 0x48, 0x08, 0xe5, 0x55, 0xdb, 0x89, 0x7c, 0xb7, 0xcc, 0xcd, 0xe2, 0x32, 0xae, 0x9c, + 0x3c, 0x69, 0x97, 0x0a, 0x98, 0xc5, 0x36, 0xed, 0xcb, 0xe5, 0xd8, 0xb2, 0x73, 0xb8, 0x1c, 0xdb, + 0x42, 0x73, 0xab, 0x50, 0x67, 0x40, 0x16, 0x17, 0x11, 0x79, 0x72, 0x47, 0x55, 0xe6, 0x7a, 0xb7, + 0xf3, 0xf3, 0x8b, 0x87, 0xaa, 0xf5, 0xfa, 0xa1, 0x6a, 0xbd, 0x79, 0xa8, 0x5a, 0x7f, 0xb5, 0x86, + 0x4c, 0xde, 0x8e, 0xfb, 0x0d, 0x2f, 0xbc, 0x6b, 0x0e, 0x39, 0xbd, 0x67, 0xba, 0x91, 0xa8, 0xdf, + 0x9c, 0xbe, 0xf9, 0x34, 0x62, 0x73, 0x7f, 0x0d, 0xfa, 0x79, 0xf5, 0xf9, 0xe9, 0x5d, 0x00, 0x00, + 0x00, 0xff, 0xff, 0xb7, 0xb8, 0x98, 0xf9, 0x78, 0x08, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -867,6 +868,9 @@ type JoinServiceClient interface { // RegisterUsingTPMMethod allows registration of a new agent or Bot to the // cluster using a known TPM. RegisterUsingTPMMethod(ctx context.Context, opts ...grpc.CallOption) (JoinService_RegisterUsingTPMMethodClient, error) + // RegisterUsingToken is used to register a new node to the cluster using one + // of the legacy join methods which do not yet have their own gRPC method. + RegisterUsingToken(ctx context.Context, in *types.RegisterUsingTokenRequest, opts ...grpc.CallOption) (*Certs, error) } type joinServiceClient struct { @@ -970,6 +974,15 @@ func (x *joinServiceRegisterUsingTPMMethodClient) Recv() (*RegisterUsingTPMMetho return m, nil } +func (c *joinServiceClient) RegisterUsingToken(ctx context.Context, in *types.RegisterUsingTokenRequest, opts ...grpc.CallOption) (*Certs, error) { + out := new(Certs) + err := c.cc.Invoke(ctx, "/proto.JoinService/RegisterUsingToken", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // JoinServiceServer is the server API for JoinService service. type JoinServiceServer interface { // RegisterUsingIAMMethod is used to register a new node to the cluster using @@ -981,6 +994,9 @@ type JoinServiceServer interface { // RegisterUsingTPMMethod allows registration of a new agent or Bot to the // cluster using a known TPM. RegisterUsingTPMMethod(JoinService_RegisterUsingTPMMethodServer) error + // RegisterUsingToken is used to register a new node to the cluster using one + // of the legacy join methods which do not yet have their own gRPC method. + RegisterUsingToken(context.Context, *types.RegisterUsingTokenRequest) (*Certs, error) } // UnimplementedJoinServiceServer can be embedded to have forward compatible implementations. @@ -996,6 +1012,9 @@ func (*UnimplementedJoinServiceServer) RegisterUsingAzureMethod(srv JoinService_ func (*UnimplementedJoinServiceServer) RegisterUsingTPMMethod(srv JoinService_RegisterUsingTPMMethodServer) error { return status.Errorf(codes.Unimplemented, "method RegisterUsingTPMMethod not implemented") } +func (*UnimplementedJoinServiceServer) RegisterUsingToken(ctx context.Context, req *types.RegisterUsingTokenRequest) (*Certs, error) { + return nil, status.Errorf(codes.Unimplemented, "method RegisterUsingToken not implemented") +} func RegisterJoinServiceServer(s *grpc.Server, srv JoinServiceServer) { s.RegisterService(&_JoinService_serviceDesc, srv) @@ -1079,10 +1098,33 @@ func (x *joinServiceRegisterUsingTPMMethodServer) Recv() (*RegisterUsingTPMMetho return m, nil } +func _JoinService_RegisterUsingToken_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(types.RegisterUsingTokenRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(JoinServiceServer).RegisterUsingToken(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.JoinService/RegisterUsingToken", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(JoinServiceServer).RegisterUsingToken(ctx, req.(*types.RegisterUsingTokenRequest)) + } + return interceptor(ctx, in, info, handler) +} + var _JoinService_serviceDesc = grpc.ServiceDesc{ ServiceName: "proto.JoinService", HandlerType: (*JoinServiceServer)(nil), - Methods: []grpc.MethodDesc{}, + Methods: []grpc.MethodDesc{ + { + MethodName: "RegisterUsingToken", + Handler: _JoinService_RegisterUsingToken_Handler, + }, + }, Streams: []grpc.StreamDesc{ { StreamName: "RegisterUsingIAMMethod", diff --git a/api/proto/teleport/legacy/client/proto/joinservice.proto b/api/proto/teleport/legacy/client/proto/joinservice.proto index 2f173401fdd2..4448558693d5 100644 --- a/api/proto/teleport/legacy/client/proto/joinservice.proto +++ b/api/proto/teleport/legacy/client/proto/joinservice.proto @@ -173,4 +173,7 @@ service JoinService { // RegisterUsingTPMMethod allows registration of a new agent or Bot to the // cluster using a known TPM. rpc RegisterUsingTPMMethod(stream RegisterUsingTPMMethodRequest) returns (stream RegisterUsingTPMMethodResponse); + // RegisterUsingToken is used to register a new node to the cluster using one + // of the legacy join methods which do not yet have their own gRPC method. + rpc RegisterUsingToken(types.RegisterUsingTokenRequest) returns (Certs); } diff --git a/lib/auth/apiserver.go b/lib/auth/apiserver.go index 2e3deefb77ba..6c05b49041d8 100644 --- a/lib/auth/apiserver.go +++ b/lib/auth/apiserver.go @@ -141,6 +141,7 @@ func NewAPIServer(config *APIConfig) (http.Handler, error) { srv.POST("/:version/trustedclusters/validate", srv.WithAuth(srv.validateTrustedCluster)) // Tokens + // TODO(strideynet): REMOVE IN 18.0.0 - this method is now gRPC srv.POST("/:version/tokens/register", srv.WithAuth(srv.registerUsingToken)) // Namespaces @@ -489,6 +490,7 @@ func rawMessage(data []byte, err error) (interface{}, error) { return &m, nil } +// TODO(strideynet): REMOVE IN v18.0.0 func (s *APIServer) registerUsingToken(auth *ServerWithRoles, w http.ResponseWriter, r *http.Request, _ httprouter.Params, version string) (interface{}, error) { var req types.RegisterUsingTokenRequest if err := httplib.ReadJSON(r, &req); err != nil { diff --git a/lib/auth/auth_with_roles.go b/lib/auth/auth_with_roles.go index c3a7edc28af1..15c186f54e0c 100644 --- a/lib/auth/auth_with_roles.go +++ b/lib/auth/auth_with_roles.go @@ -573,6 +573,11 @@ func (a *ServerWithRoles) GetClusterCACert( return a.authServer.GetClusterCACert(ctx) } +// Deprecated: This method only exists to service the RegisterUsingToken HTTP +// RPC, which has been replaced by an RPC on the JoinServiceServer. +// JoinServiceServer directly invokes auth.Server and performs its own checks +// on metadata. +// TODO(strideynet): DELETE IN V18.0.0 func (a *ServerWithRoles) RegisterUsingToken(ctx context.Context, req *types.RegisterUsingTokenRequest) (*proto.Certs, error) { isProxy := a.hasBuiltinRole(types.RoleProxy) @@ -615,48 +620,6 @@ func (a *ServerWithRoles) RegisterUsingToken(ctx context.Context, req *types.Reg return a.authServer.RegisterUsingToken(ctx, req) } -// RegisterUsingIAMMethod registers the caller using the IAM join method and -// returns signed certs to join the cluster. -// -// See (*Server).RegisterUsingIAMMethod for further documentation. -// -// This wrapper does not do any extra authz checks, as the register method has -// its own authz mechanism. -func (a *ServerWithRoles) RegisterUsingIAMMethod(ctx context.Context, challengeResponse client.RegisterIAMChallengeResponseFunc) (*proto.Certs, error) { - certs, err := a.authServer.RegisterUsingIAMMethod(ctx, challengeResponse) - return certs, trace.Wrap(err) -} - -// RegisterUsingAzureMethod registers the caller using the Azure join method and -// returns signed certs to join the cluster. -// -// See (*Server).RegisterUsingAzureMethod for further documentation. -// -// This wrapper does not do any extra authz checks, as the register method has -// its own authz mechanism. -func (a *ServerWithRoles) RegisterUsingAzureMethod(ctx context.Context, challengeResponse client.RegisterAzureChallengeResponseFunc) (*proto.Certs, error) { - certs, err := a.authServer.RegisterUsingAzureMethod(ctx, challengeResponse) - return certs, trace.Wrap(err) -} - -// RegisterUsingTPMMethod registers the caller using the TPM join method and -// returns signed certs to join the cluster. -// -// See (*Server).RegisterUsingTPMMethod for further documentation. -// -// This wrapper does not do any extra authz checks, as the register method has -// its own authz mechanism. -func (a *ServerWithRoles) RegisterUsingTPMMethod( - ctx context.Context, - initReq *proto.RegisterUsingTPMMethodInitialRequest, - solveChallenge client.RegisterTPMChallengeResponseFunc, -) (*proto.Certs, error) { - certs, err := a.authServer.registerUsingTPMMethod( - ctx, initReq, solveChallenge, - ) - return certs, trace.Wrap(err) -} - // GenerateHostCerts generates new host certificates (signed // by the host certificate authority) for a node. func (a *ServerWithRoles) GenerateHostCerts(ctx context.Context, req *proto.HostCertsRequest) (*proto.Certs, error) { diff --git a/lib/auth/authclient/http_client.go b/lib/auth/authclient/http_client.go index f2a9f696fc36..5845c6f20227 100644 --- a/lib/auth/authclient/http_client.go +++ b/lib/auth/authclient/http_client.go @@ -33,7 +33,6 @@ import ( "github.com/gravitational/teleport" "github.com/gravitational/teleport/api/breaker" "github.com/gravitational/teleport/api/client" - "github.com/gravitational/teleport/api/client/proto" "github.com/gravitational/teleport/api/constants" apidefaults "github.com/gravitational/teleport/api/defaults" tracehttp "github.com/gravitational/teleport/api/observability/tracing/http" @@ -336,25 +335,6 @@ func (c *HTTPClient) ProcessKubeCSR(req KubeCSR) (*KubeCSRResponse, error) { return &re, nil } -// RegisterUsingToken calls the auth service API to register a new node using a registration token -// which was previously issued via CreateToken/UpsertToken. -func (c *HTTPClient) RegisterUsingToken(ctx context.Context, req *types.RegisterUsingTokenRequest) (*proto.Certs, error) { - if err := req.CheckAndSetDefaults(); err != nil { - return nil, trace.Wrap(err) - } - out, err := c.PostJSON(ctx, c.Endpoint("tokens", "register"), req) - 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 -} - type upsertTunnelConnectionRawReq struct { TunnelConnection json.RawMessage `json:"tunnel_connection"` } diff --git a/lib/auth/authclient/httpfallback.go b/lib/auth/authclient/httpfallback.go index 58d665e12ba1..6117a003871b 100644 --- a/lib/auth/authclient/httpfallback.go +++ b/lib/auth/authclient/httpfallback.go @@ -26,6 +26,7 @@ import ( "github.com/gravitational/trace" + "github.com/gravitational/teleport/api/client/proto" "github.com/gravitational/teleport/api/types" "github.com/gravitational/teleport/lib/services" ) @@ -126,3 +127,41 @@ func (c *Client) deleteReverseTunnelLegacy(ctx context.Context, domainName strin _, err := c.Delete(ctx, c.Endpoint("reversetunnels", domainName)) return trace.Wrap(err) } + +// RegisterUsingToken calls the auth service API to register a new node using a +// registration token which was previously issued via CreateToken/UpsertToken. +func (c *Client) RegisterUsingToken( + ctx context.Context, req *types.RegisterUsingTokenRequest, +) (*proto.Certs, error) { + if err := req.CheckAndSetDefaults(); err != nil { + return nil, trace.Wrap(err) + } + certs, err := c.APIClient.RegisterUsingToken(ctx, req) + if err == nil { + return certs, nil + } + if !trace.IsNotImplemented(err) { + return nil, trace.Wrap(err) + } + + return c.registerUsingTokenLegacy(ctx, req) +} + +func (c *HTTPClient) registerUsingTokenLegacy( + ctx context.Context, req *types.RegisterUsingTokenRequest, +) (*proto.Certs, error) { + if err := req.CheckAndSetDefaults(); err != nil { + return nil, trace.Wrap(err) + } + out, err := c.PostJSON(ctx, c.Endpoint("tokens", "register"), req) + 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 +} diff --git a/lib/auth/bot_test.go b/lib/auth/bot_test.go index 5ec0af8421dc..14e9fd8c931f 100644 --- a/lib/auth/bot_test.go +++ b/lib/auth/bot_test.go @@ -599,7 +599,7 @@ func TestRegisterBot_RemoteAddr(t *testing.T) { pkey, err := x509.ParsePKCS1PrivateKey(block.Bytes) require.NoError(t, err) - certs, err := a.RegisterUsingAzureMethod(context.Background(), func(challenge string) (*proto.RegisterUsingAzureMethodRequest, error) { + certs, err := a.RegisterUsingAzureMethodWithOpts(context.Background(), func(challenge string) (*proto.RegisterUsingAzureMethodRequest, error) { ad := attestedData{ Nonce: challenge, SubscriptionID: subID, diff --git a/lib/auth/grpcserver.go b/lib/auth/grpcserver.go index abab08063efa..e0e39b17de0d 100644 --- a/lib/auth/grpcserver.go +++ b/lib/auth/grpcserver.go @@ -5164,12 +5164,7 @@ func NewGRPCServer(cfg GRPCServerConfig) (*GRPCServer, error) { } trustv1pb.RegisterTrustServiceServer(server, trust) - // create server with no-op role to pass to JoinService server - serverWithNopRole, err := serverWithNopRole(cfg) - if err != nil { - return nil, trace.Wrap(err) - } - joinServiceServer := joinserver.NewJoinServiceGRPCServer(serverWithNopRole) + joinServiceServer := joinserver.NewJoinServiceGRPCServer(cfg.AuthServer) authpb.RegisterJoinServiceServer(server, joinServiceServer) integrationServiceServer, err := integrationv1.NewService(&integrationv1.ServiceConfig{ @@ -5356,31 +5351,6 @@ func NewGRPCServer(cfg GRPCServerConfig) (*GRPCServer, error) { return authServer, nil } -func serverWithNopRole(cfg GRPCServerConfig) (*ServerWithRoles, error) { - clusterName, err := cfg.AuthServer.GetClusterName() - if err != nil { - return nil, trace.Wrap(err) - } - nopRole := authz.BuiltinRole{ - Role: types.RoleNop, - Username: string(types.RoleNop), - ClusterName: clusterName.GetClusterName(), - } - recConfig, err := cfg.AuthServer.GetSessionRecordingConfig(context.Background()) - if err != nil { - return nil, trace.Wrap(err) - } - nopCtx, err := authz.ContextForBuiltinRole(nopRole, recConfig) - if err != nil { - return nil, trace.Wrap(err) - } - return &ServerWithRoles{ - authServer: cfg.AuthServer, - context: *nopCtx, - alog: cfg.AuthServer, - }, nil -} - type grpcContext struct { *authz.Context *ServerWithRoles diff --git a/lib/auth/join/join.go b/lib/auth/join/join.go index 038a8a693283..ba7be300dc85 100644 --- a/lib/auth/join/join.go +++ b/lib/auth/join/join.go @@ -100,6 +100,8 @@ type RegisterParams struct { CAPath string // GetHostCredentials is a client that can fetch host credentials. // Ignored if AuthClient is provided. + // TODO(strideynet): REMOVE IN V18.0.0 + // Deprecated: since v17, the API client can be used for this purpose. GetHostCredentials HostCredentials // Clock specifies the time provider. Will be used to override the time anchor // for TLS certificate verification. @@ -348,26 +350,25 @@ func registerThroughProxy( return nil, trace.Wrap(err) } + conn, err := proxyinsecureclient.NewConnection( + ctx, + proxyinsecureclient.ConnectionConfig{ + ProxyServer: proxyAddr, + CipherSuites: params.CipherSuites, + Clock: params.Clock, + Insecure: params.Insecure, + Log: slog.Default(), + }, + ) + if err != nil { + return nil, trace.Wrap(err) + } + defer conn.Close() + joinServiceClient := client.NewJoinServiceClient(proto.NewJoinServiceClient(conn)) + var certs *proto.Certs switch params.JoinMethod { case types.JoinMethodIAM, types.JoinMethodAzure, types.JoinMethodTPM: - // IAM and Azure join methods require gRPC client - conn, err := proxyinsecureclient.NewConnection( - ctx, - proxyinsecureclient.ConnectionConfig{ - ProxyServer: proxyAddr, - CipherSuites: params.CipherSuites, - Clock: params.Clock, - Insecure: params.Insecure, - Log: slog.Default(), - }, - ) - if err != nil { - return nil, trace.Wrap(err) - } - defer conn.Close() - - joinServiceClient := client.NewJoinServiceClient(proto.NewJoinServiceClient(conn)) switch params.JoinMethod { case types.JoinMethodIAM: certs, err = registerUsingIAMMethod(ctx, joinServiceClient, token, hostKeys, params) @@ -382,17 +383,30 @@ func registerThroughProxy( return nil, trace.Wrap(err) } default: - // The rest of the join methods use GetHostCredentials function passed through - // params to call proxy HTTP endpoint - var err error - certs, err = params.GetHostCredentials(ctx, - proxyAddr, - params.Insecure, - *registerUsingTokenRequestForParams(token, hostKeys, params)) + certs, err = joinServiceClient.RegisterUsingToken( + ctx, registerUsingTokenRequestForParams(token, hostKeys, params), + ) if err != nil { - return nil, trace.Wrap(err) + // The rest of the join methods use the RegisterUsingToken RPC + // TODO(strideynet): in V18.0.0, we can remove the fallback call to + // GetHostCredentials. + if !trace.IsNotImplemented(err) { + return nil, trace.Wrap(err) + } + slog.WarnContext( + ctx, + "Registration falling back to deprecated HTTP API. Your agent may be newer than the Auth Server.", + ) + certs, err = params.GetHostCredentials(ctx, + proxyAddr, + params.Insecure, + *registerUsingTokenRequestForParams(token, hostKeys, params)) + if err != nil { + return nil, trace.Wrap(err) + } } } + return &RegisterResult{ Certs: certs, PrivateKey: hostKeys.privateKey, diff --git a/lib/auth/join_azure.go b/lib/auth/join_azure.go index e044d4e810a6..9cee8259dd4c 100644 --- a/lib/auth/join_azure.go +++ b/lib/auth/join_azure.go @@ -351,13 +351,13 @@ func generateAzureChallenge() (string, error) { return challenge, trace.Wrap(err) } -// RegisterUsingAzureMethod registers the caller using the Azure join method +// RegisterUsingAzureMethodWithOpts registers the caller using the Azure join method // and returns signed certs to join the cluster. // // The caller must provide a ChallengeResponseFunc which returns a // *proto.RegisterUsingAzureMethodRequest with a signed attested data document // including the challenge as a nonce. -func (a *Server) RegisterUsingAzureMethod( +func (a *Server) RegisterUsingAzureMethodWithOpts( ctx context.Context, challengeResponse client.RegisterAzureChallengeResponseFunc, opts ...azureRegisterOption, @@ -422,6 +422,19 @@ func (a *Server) RegisterUsingAzureMethod( return certs, trace.Wrap(err) } +// RegisterUsingAzureMethod registers the caller using the Azure join method +// and returns signed certs to join the cluster. +// +// The caller must provide a ChallengeResponseFunc which returns a +// *proto.RegisterUsingAzureMethodRequest with a signed attested data document +// including the challenge as a nonce. +func (a *Server) RegisterUsingAzureMethod( + ctx context.Context, + challengeResponse client.RegisterAzureChallengeResponseFunc, +) (certs *proto.Certs, err error) { + return a.RegisterUsingAzureMethodWithOpts(ctx, challengeResponse) +} + // fixAzureSigningAlgorithm fixes a mismatch between the object IDs of the // hashing algorithm sent by Azure vs the ones expected by the pkcs7 library. // Specifically, Azure (incorrectly?) sends a [digest encryption algorithm] diff --git a/lib/auth/join_azure_test.go b/lib/auth/join_azure_test.go index 5fe5d487fcf3..1e8af282de7e 100644 --- a/lib/auth/join_azure_test.go +++ b/lib/auth/join_azure_test.go @@ -419,7 +419,7 @@ func TestAuth_RegisterUsingAzureMethod(t *testing.T) { vmClient := &mockAzureVMClient{vm: vmResult} - _, err = a.RegisterUsingAzureMethod(context.Background(), func(challenge string) (*proto.RegisterUsingAzureMethodRequest, error) { + _, err = a.RegisterUsingAzureMethodWithOpts(context.Background(), func(challenge string) (*proto.RegisterUsingAzureMethodRequest, error) { cfg := &azureChallengeResponseConfig{Challenge: challenge} for _, opt := range tc.challengeResponseOptions { opt(cfg) diff --git a/lib/auth/join_iam.go b/lib/auth/join_iam.go index a43fbe70fd92..ba2209105c7c 100644 --- a/lib/auth/join_iam.go +++ b/lib/auth/join_iam.go @@ -328,13 +328,13 @@ func withFips(fips bool) iamRegisterOption { } } -// RegisterUsingIAMMethod registers the caller using the IAM join method and +// RegisterUsingIAMMethodWithOpts registers the caller using the IAM join method and // returns signed certs to join the cluster. // // The caller must provide a ChallengeResponseFunc which returns a // *types.RegisterUsingTokenRequest with a signed sts:GetCallerIdentity request // including the challenge as a signed header. -func (a *Server) RegisterUsingIAMMethod( +func (a *Server) RegisterUsingIAMMethodWithOpts( ctx context.Context, challengeResponse client.RegisterIAMChallengeResponseFunc, opts ...iamRegisterOption, @@ -388,3 +388,16 @@ func (a *Server) RegisterUsingIAMMethod( certs, err = a.generateCerts(ctx, provisionToken, req.RegisterUsingTokenRequest, nil) return certs, trace.Wrap(err, "generating certs") } + +// RegisterUsingIAMMethod registers the caller using the IAM join method and +// returns signed certs to join the cluster. +// +// The caller must provide a ChallengeResponseFunc which returns a +// *types.RegisterUsingTokenRequest with a signed sts:GetCallerIdentity request +// including the challenge as a signed header. +func (a *Server) RegisterUsingIAMMethod( + ctx context.Context, + challengeResponse client.RegisterIAMChallengeResponseFunc, +) (certs *proto.Certs, err error) { + return a.RegisterUsingIAMMethodWithOpts(ctx, challengeResponse) +} diff --git a/lib/auth/join_iam_test.go b/lib/auth/join_iam_test.go index 5ba3d6ae76c2..a64399d6e713 100644 --- a/lib/auth/join_iam_test.go +++ b/lib/auth/join_iam_test.go @@ -620,7 +620,7 @@ func TestAuth_RegisterUsingIAMMethod(t *testing.T) { require.NoError(t, a.DeleteToken(ctx, token.GetName())) }() - _, err = a.RegisterUsingIAMMethod(context.Background(), func(challenge string) (*proto.RegisterUsingIAMMethodRequest, error) { + _, err = a.RegisterUsingIAMMethodWithOpts(context.Background(), func(challenge string) (*proto.RegisterUsingIAMMethodRequest, error) { templateInput := defaultIdentityRequestTemplateInput(challenge) for _, opt := range tc.challengeResponseOptions { opt(&templateInput) diff --git a/lib/auth/join_tpm.go b/lib/auth/join_tpm.go index 4304628b9d07..05bf9e3c35a5 100644 --- a/lib/auth/join_tpm.go +++ b/lib/auth/join_tpm.go @@ -33,7 +33,7 @@ import ( "github.com/gravitational/teleport/lib/tpm" ) -func (a *Server) registerUsingTPMMethod( +func (a *Server) RegisterUsingTPMMethod( ctx context.Context, initReq *proto.RegisterUsingTPMMethodInitialRequest, solveChallenge client.RegisterTPMChallengeResponseFunc, diff --git a/lib/auth/join_tpm_test.go b/lib/auth/join_tpm_test.go index 8210a2f97518..edfe2b448115 100644 --- a/lib/auth/join_tpm_test.go +++ b/lib/auth/join_tpm_test.go @@ -340,7 +340,7 @@ func TestServer_RegisterUsingTPMMethod(t *testing.T) { require.NoError(t, auth.CreateToken(ctx, token)) tt.initReq.JoinRequest.Token = tt.name - _, err = auth.registerUsingTPMMethod( + _, err = auth.RegisterUsingTPMMethod( ctx, tt.initReq, solver(t)) diff --git a/lib/client/weblogin.go b/lib/client/weblogin.go index 48e35696d8f5..11434d68a022 100644 --- a/lib/client/weblogin.go +++ b/lib/client/weblogin.go @@ -756,6 +756,8 @@ func newMFALoginCeremony(clt *WebClient, login SSHLoginMFA) *mfa.Ceremony { } // HostCredentials is used to fetch host credentials for a node. +// TODO(noah): REMOVE IN V18.0.0 +// Deprecated: Use the RegisterUsingToken gRPC method instead. func HostCredentials(ctx context.Context, proxyAddr string, insecure bool, req types.RegisterUsingTokenRequest) (*proto.Certs, error) { clt, _, err := initClient(proxyAddr, insecure, nil, nil) if err != nil { diff --git a/lib/joinserver/joinserver.go b/lib/joinserver/joinserver.go index 735dae1e6ab0..20933b02a4f9 100644 --- a/lib/joinserver/joinserver.go +++ b/lib/joinserver/joinserver.go @@ -53,6 +53,10 @@ type joinServiceClient interface { initReq *proto.RegisterUsingTPMMethodInitialRequest, solveChallenge client.RegisterTPMChallengeResponseFunc, ) (*proto.Certs, error) + RegisterUsingToken( + ctx context.Context, + req *types.RegisterUsingTokenRequest, + ) (*proto.Certs, error) } // JoinServiceGRPCServer implements proto.JoinServiceServer and is designed @@ -210,6 +214,10 @@ func setClientRemoteAddr(ctx context.Context, req *types.RegisterUsingTokenReque func setBotParameters(ctx context.Context, req *types.RegisterUsingTokenRequest) { user, err := authz.UserFromContext(ctx) if err != nil { + // No authenticated user, we don't want to trust the values provided in + // the request unless it's coming from a proxy. + req.BotInstanceID = "" + req.BotGeneration = 0 return } @@ -376,3 +384,19 @@ func (s *JoinServiceGRPCServer) registerUsingTPMMethod( }, })) } + +// RegisterUsingToken allows nodes and proxies to join the cluster using +// legacy join methods which do not yet have their own RPC. +// On the Auth server, this method will call the auth.Server's +// RegisterUsingToken method. When running on the Proxy, this method will +// forward the request to the Auth server's JoinServiceServer. +func (s *JoinServiceGRPCServer) RegisterUsingToken( + ctx context.Context, req *types.RegisterUsingTokenRequest, +) (*proto.Certs, error) { + if err := setClientRemoteAddr(ctx, req); err != nil { + return nil, trace.Wrap(err, "setting client address") + } + setBotParameters(ctx, req) + + return s.joinServiceClient.RegisterUsingToken(ctx, req) +} diff --git a/lib/joinserver/joinserver_test.go b/lib/joinserver/joinserver_test.go index bf3226b24d32..68c68757391e 100644 --- a/lib/joinserver/joinserver_test.go +++ b/lib/joinserver/joinserver_test.go @@ -49,6 +49,7 @@ type mockJoinServiceClient struct { gotAzureChallengeResponse *proto.RegisterUsingAzureMethodRequest gotTPMChallengeResponse *proto.RegisterUsingTPMMethodChallengeResponse gotTPMInitReq *proto.RegisterUsingTPMMethodInitialRequest + gotRegisterUsingTokenReq *types.RegisterUsingTokenRequest } func (c *mockJoinServiceClient) RegisterUsingIAMMethod(ctx context.Context, challengeResponse client.RegisterIAMChallengeResponseFunc) (*proto.Certs, error) { @@ -85,6 +86,14 @@ func (c *mockJoinServiceClient) RegisterUsingTPMMethod( return c.returnCerts, c.returnError } +func (c *mockJoinServiceClient) RegisterUsingToken( + ctx context.Context, + req *types.RegisterUsingTokenRequest, +) (*proto.Certs, error) { + c.gotRegisterUsingTokenReq = req + return c.returnCerts, c.returnError +} + func ConnectionCountingStreamInterceptor(count *atomic.Int32) grpc.StreamServerInterceptor { return func(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error { count.Add(1) @@ -323,6 +332,88 @@ func TestJoinServiceGRPCServer_RegisterUsingAzureMethod(t *testing.T) { } } +func TestJoinServiceGRPCServer_RegisterUsingToken(t *testing.T) { + t.Parallel() + testPack := newTestPack(t) + + testCases := []struct { + desc string + req *types.RegisterUsingTokenRequest + wantReq *types.RegisterUsingTokenRequest + authErr string + certs *proto.Certs + }{ + { + desc: "unauthenticated pass case", + req: &types.RegisterUsingTokenRequest{ + Token: "xyzzy", + }, + wantReq: &types.RegisterUsingTokenRequest{ + Token: "xyzzy", + RemoteAddr: "bufconn", + }, + certs: &proto.Certs{SSH: []byte("qux")}, + }, + { + desc: "unauthenticated - faked metadata ignored", + req: &types.RegisterUsingTokenRequest{ + Token: "xyzzy", + RemoteAddr: "mauahahh", + BotInstanceID: "123-456", + BotGeneration: 1337, + }, + wantReq: &types.RegisterUsingTokenRequest{ + Token: "xyzzy", + RemoteAddr: "bufconn", + }, + certs: &proto.Certs{SSH: []byte("qux")}, + }, + { + desc: "auth error", + req: &types.RegisterUsingTokenRequest{ + Token: "xyzzy", + }, + wantReq: &types.RegisterUsingTokenRequest{ + Token: "xyzzy", + RemoteAddr: "bufconn", + }, + authErr: "test auth error", + }, + } + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + testPack.mockAuthServer.returnCerts = tc.certs + if tc.authErr != "" { + testPack.mockAuthServer.returnError = errors.New(tc.authErr) + } + + for suffix, clt := range map[string]*client.JoinServiceClient{ + "_auth": testPack.authClient, + "_proxy": testPack.proxyClient, + } { + t.Run(tc.desc+suffix, func(t *testing.T) { + certs, err := clt.RegisterUsingToken( + context.Background(), + tc.req, + ) + if tc.authErr != "" { + require.ErrorContains(t, err, tc.authErr, "authErr mismatch") + return + } + if assert.NoError(t, err) { + assert.Equal(t, tc.certs, certs) + } + assert.Equal( + t, + tc.wantReq, + testPack.mockAuthServer.gotRegisterUsingTokenReq, + ) + }) + } + }) + } +} + func TestJoinServiceGRPCServer_RegisterUsingTPMMethod(t *testing.T) { t.Parallel() testPack := newTestPack(t) diff --git a/lib/web/apiserver.go b/lib/web/apiserver.go index 8e1e4ba43f69..d2957b56e2ec 100644 --- a/lib/web/apiserver.go +++ b/lib/web/apiserver.go @@ -4067,6 +4067,8 @@ type eventsListGetResponse struct { // hostCredentials sends a registration token and metadata to the Auth Server // and gets back SSH and TLS certificates. +// TODO(strideynet): DELETE IN V18.0.0 +// Deprecated: Use the RegisterUsingToken RPC instead. func (h *Handler) hostCredentials(w http.ResponseWriter, r *http.Request, p httprouter.Params) (interface{}, error) { var req types.RegisterUsingTokenRequest if err := httplib.ReadJSON(r, &req); err != nil {