Move SudoPrivilege out of SystemView (#7266)

* Move SudoPrivilege out of SystemView

We only use this in token store and it literally doesn't work anything
that isn't the token store or system mount, so we should stop exposing
something that doesn't work.

* Reconcile extended system view with sdk/logical a bit and put an explanation for why SudoPrivilege isn't moved over
This commit is contained in:
Jeff Mitchell 2019-08-26 10:23:46 -04:00 committed by GitHub
parent 366add2979
commit 9816963355
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 208 additions and 385 deletions

View file

@ -22,10 +22,6 @@ type SystemView interface {
// this value, as Vault will revoke them // this value, as Vault will revoke them
MaxLeaseTTL() time.Duration MaxLeaseTTL() time.Duration
// SudoPrivilege returns true if given path has sudo privileges
// for the given client token
SudoPrivilege(ctx context.Context, path string, token string) bool
// Returns true if the mount is tainted. A mount is tainted if it is in the // Returns true if the mount is tainted. A mount is tainted if it is in the
// process of being unmounted. This should only be used in special // process of being unmounted. This should only be used in special
// circumstances; a primary use-case is as a guard in revocation functions. // circumstances; a primary use-case is as a guard in revocation functions.

View file

@ -44,18 +44,6 @@ func (s *gRPCSystemViewClient) MaxLeaseTTL() time.Duration {
return time.Duration(reply.TTL) return time.Duration(reply.TTL)
} }
func (s *gRPCSystemViewClient) SudoPrivilege(ctx context.Context, path string, token string) bool {
reply, err := s.client.SudoPrivilege(ctx, &pb.SudoPrivilegeArgs{
Path: path,
Token: token,
})
if err != nil {
return false
}
return reply.Sudo
}
func (s *gRPCSystemViewClient) Tainted() bool { func (s *gRPCSystemViewClient) Tainted() bool {
reply, err := s.client.Tainted(context.Background(), &pb.Empty{}) reply, err := s.client.Tainted(context.Background(), &pb.Empty{})
if err != nil { if err != nil {
@ -177,13 +165,6 @@ func (s *gRPCSystemViewServer) MaxLeaseTTL(ctx context.Context, _ *pb.Empty) (*p
}, nil }, nil
} }
func (s *gRPCSystemViewServer) SudoPrivilege(ctx context.Context, args *pb.SudoPrivilegeArgs) (*pb.SudoPrivilegeReply, error) {
sudo := s.impl.SudoPrivilege(ctx, args.Path, args.Token)
return &pb.SudoPrivilegeReply{
Sudo: sudo,
}, nil
}
func (s *gRPCSystemViewServer) Tainted(ctx context.Context, _ *pb.Empty) (*pb.TaintedReply, error) { func (s *gRPCSystemViewServer) Tainted(ctx context.Context, _ *pb.Empty) (*pb.TaintedReply, error) {
tainted := s.impl.Tainted() tainted := s.impl.Tainted()
return &pb.TaintedReply{ return &pb.TaintedReply{

View file

@ -53,26 +53,6 @@ func TestSystem_GRPC_maxLeaseTTL(t *testing.T) {
} }
} }
func TestSystem_GRPC_sudoPrivilege(t *testing.T) {
sys := logical.TestSystemView()
sys.SudoPrivilegeVal = true
client, _ := plugin.TestGRPCConn(t, func(s *grpc.Server) {
pb.RegisterSystemViewServer(s, &gRPCSystemViewServer{
impl: sys,
})
})
defer client.Close()
testSystemView := newGRPCSystemView(client)
ctx := context.Background()
expected := sys.SudoPrivilege(ctx, "foo", "bar")
actual := testSystemView.SudoPrivilege(ctx, "foo", "bar")
if !reflect.DeepEqual(expected, actual) {
t.Fatalf("expected: %v, got: %v", expected, actual)
}
}
func TestSystem_GRPC_tainted(t *testing.T) { func TestSystem_GRPC_tainted(t *testing.T) {
sys := logical.TestSystemView() sys := logical.TestSystemView()
sys.TaintedVal = true sys.TaintedVal = true

View file

@ -2185,92 +2185,6 @@ func (m *TTLReply) GetTTL() int64 {
return 0 return 0
} }
type SudoPrivilegeArgs struct {
Path string `sentinel:"" protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"`
Token string `sentinel:"" protobuf:"bytes,2,opt,name=token,proto3" json:"token,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *SudoPrivilegeArgs) Reset() { *m = SudoPrivilegeArgs{} }
func (m *SudoPrivilegeArgs) String() string { return proto.CompactTextString(m) }
func (*SudoPrivilegeArgs) ProtoMessage() {}
func (*SudoPrivilegeArgs) Descriptor() ([]byte, []int) {
return fileDescriptor_4dbf1dfe0c11846b, []int{33}
}
func (m *SudoPrivilegeArgs) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_SudoPrivilegeArgs.Unmarshal(m, b)
}
func (m *SudoPrivilegeArgs) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_SudoPrivilegeArgs.Marshal(b, m, deterministic)
}
func (m *SudoPrivilegeArgs) XXX_Merge(src proto.Message) {
xxx_messageInfo_SudoPrivilegeArgs.Merge(m, src)
}
func (m *SudoPrivilegeArgs) XXX_Size() int {
return xxx_messageInfo_SudoPrivilegeArgs.Size(m)
}
func (m *SudoPrivilegeArgs) XXX_DiscardUnknown() {
xxx_messageInfo_SudoPrivilegeArgs.DiscardUnknown(m)
}
var xxx_messageInfo_SudoPrivilegeArgs proto.InternalMessageInfo
func (m *SudoPrivilegeArgs) GetPath() string {
if m != nil {
return m.Path
}
return ""
}
func (m *SudoPrivilegeArgs) GetToken() string {
if m != nil {
return m.Token
}
return ""
}
type SudoPrivilegeReply struct {
Sudo bool `sentinel:"" protobuf:"varint,1,opt,name=sudo,proto3" json:"sudo,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *SudoPrivilegeReply) Reset() { *m = SudoPrivilegeReply{} }
func (m *SudoPrivilegeReply) String() string { return proto.CompactTextString(m) }
func (*SudoPrivilegeReply) ProtoMessage() {}
func (*SudoPrivilegeReply) Descriptor() ([]byte, []int) {
return fileDescriptor_4dbf1dfe0c11846b, []int{34}
}
func (m *SudoPrivilegeReply) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_SudoPrivilegeReply.Unmarshal(m, b)
}
func (m *SudoPrivilegeReply) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_SudoPrivilegeReply.Marshal(b, m, deterministic)
}
func (m *SudoPrivilegeReply) XXX_Merge(src proto.Message) {
xxx_messageInfo_SudoPrivilegeReply.Merge(m, src)
}
func (m *SudoPrivilegeReply) XXX_Size() int {
return xxx_messageInfo_SudoPrivilegeReply.Size(m)
}
func (m *SudoPrivilegeReply) XXX_DiscardUnknown() {
xxx_messageInfo_SudoPrivilegeReply.DiscardUnknown(m)
}
var xxx_messageInfo_SudoPrivilegeReply proto.InternalMessageInfo
func (m *SudoPrivilegeReply) GetSudo() bool {
if m != nil {
return m.Sudo
}
return false
}
type TaintedReply struct { type TaintedReply struct {
Tainted bool `sentinel:"" protobuf:"varint,1,opt,name=tainted,proto3" json:"tainted,omitempty"` Tainted bool `sentinel:"" protobuf:"varint,1,opt,name=tainted,proto3" json:"tainted,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
@ -2282,7 +2196,7 @@ func (m *TaintedReply) Reset() { *m = TaintedReply{} }
func (m *TaintedReply) String() string { return proto.CompactTextString(m) } func (m *TaintedReply) String() string { return proto.CompactTextString(m) }
func (*TaintedReply) ProtoMessage() {} func (*TaintedReply) ProtoMessage() {}
func (*TaintedReply) Descriptor() ([]byte, []int) { func (*TaintedReply) Descriptor() ([]byte, []int) {
return fileDescriptor_4dbf1dfe0c11846b, []int{35} return fileDescriptor_4dbf1dfe0c11846b, []int{33}
} }
func (m *TaintedReply) XXX_Unmarshal(b []byte) error { func (m *TaintedReply) XXX_Unmarshal(b []byte) error {
@ -2321,7 +2235,7 @@ func (m *CachingDisabledReply) Reset() { *m = CachingDisabledReply{} }
func (m *CachingDisabledReply) String() string { return proto.CompactTextString(m) } func (m *CachingDisabledReply) String() string { return proto.CompactTextString(m) }
func (*CachingDisabledReply) ProtoMessage() {} func (*CachingDisabledReply) ProtoMessage() {}
func (*CachingDisabledReply) Descriptor() ([]byte, []int) { func (*CachingDisabledReply) Descriptor() ([]byte, []int) {
return fileDescriptor_4dbf1dfe0c11846b, []int{36} return fileDescriptor_4dbf1dfe0c11846b, []int{34}
} }
func (m *CachingDisabledReply) XXX_Unmarshal(b []byte) error { func (m *CachingDisabledReply) XXX_Unmarshal(b []byte) error {
@ -2360,7 +2274,7 @@ func (m *ReplicationStateReply) Reset() { *m = ReplicationStateReply{} }
func (m *ReplicationStateReply) String() string { return proto.CompactTextString(m) } func (m *ReplicationStateReply) String() string { return proto.CompactTextString(m) }
func (*ReplicationStateReply) ProtoMessage() {} func (*ReplicationStateReply) ProtoMessage() {}
func (*ReplicationStateReply) Descriptor() ([]byte, []int) { func (*ReplicationStateReply) Descriptor() ([]byte, []int) {
return fileDescriptor_4dbf1dfe0c11846b, []int{37} return fileDescriptor_4dbf1dfe0c11846b, []int{35}
} }
func (m *ReplicationStateReply) XXX_Unmarshal(b []byte) error { func (m *ReplicationStateReply) XXX_Unmarshal(b []byte) error {
@ -2401,7 +2315,7 @@ func (m *ResponseWrapDataArgs) Reset() { *m = ResponseWrapDataArgs{} }
func (m *ResponseWrapDataArgs) String() string { return proto.CompactTextString(m) } func (m *ResponseWrapDataArgs) String() string { return proto.CompactTextString(m) }
func (*ResponseWrapDataArgs) ProtoMessage() {} func (*ResponseWrapDataArgs) ProtoMessage() {}
func (*ResponseWrapDataArgs) Descriptor() ([]byte, []int) { func (*ResponseWrapDataArgs) Descriptor() ([]byte, []int) {
return fileDescriptor_4dbf1dfe0c11846b, []int{38} return fileDescriptor_4dbf1dfe0c11846b, []int{36}
} }
func (m *ResponseWrapDataArgs) XXX_Unmarshal(b []byte) error { func (m *ResponseWrapDataArgs) XXX_Unmarshal(b []byte) error {
@ -2455,7 +2369,7 @@ func (m *ResponseWrapDataReply) Reset() { *m = ResponseWrapDataReply{} }
func (m *ResponseWrapDataReply) String() string { return proto.CompactTextString(m) } func (m *ResponseWrapDataReply) String() string { return proto.CompactTextString(m) }
func (*ResponseWrapDataReply) ProtoMessage() {} func (*ResponseWrapDataReply) ProtoMessage() {}
func (*ResponseWrapDataReply) Descriptor() ([]byte, []int) { func (*ResponseWrapDataReply) Descriptor() ([]byte, []int) {
return fileDescriptor_4dbf1dfe0c11846b, []int{39} return fileDescriptor_4dbf1dfe0c11846b, []int{37}
} }
func (m *ResponseWrapDataReply) XXX_Unmarshal(b []byte) error { func (m *ResponseWrapDataReply) XXX_Unmarshal(b []byte) error {
@ -2501,7 +2415,7 @@ func (m *MlockEnabledReply) Reset() { *m = MlockEnabledReply{} }
func (m *MlockEnabledReply) String() string { return proto.CompactTextString(m) } func (m *MlockEnabledReply) String() string { return proto.CompactTextString(m) }
func (*MlockEnabledReply) ProtoMessage() {} func (*MlockEnabledReply) ProtoMessage() {}
func (*MlockEnabledReply) Descriptor() ([]byte, []int) { func (*MlockEnabledReply) Descriptor() ([]byte, []int) {
return fileDescriptor_4dbf1dfe0c11846b, []int{40} return fileDescriptor_4dbf1dfe0c11846b, []int{38}
} }
func (m *MlockEnabledReply) XXX_Unmarshal(b []byte) error { func (m *MlockEnabledReply) XXX_Unmarshal(b []byte) error {
@ -2540,7 +2454,7 @@ func (m *LocalMountReply) Reset() { *m = LocalMountReply{} }
func (m *LocalMountReply) String() string { return proto.CompactTextString(m) } func (m *LocalMountReply) String() string { return proto.CompactTextString(m) }
func (*LocalMountReply) ProtoMessage() {} func (*LocalMountReply) ProtoMessage() {}
func (*LocalMountReply) Descriptor() ([]byte, []int) { func (*LocalMountReply) Descriptor() ([]byte, []int) {
return fileDescriptor_4dbf1dfe0c11846b, []int{41} return fileDescriptor_4dbf1dfe0c11846b, []int{39}
} }
func (m *LocalMountReply) XXX_Unmarshal(b []byte) error { func (m *LocalMountReply) XXX_Unmarshal(b []byte) error {
@ -2579,7 +2493,7 @@ func (m *EntityInfoArgs) Reset() { *m = EntityInfoArgs{} }
func (m *EntityInfoArgs) String() string { return proto.CompactTextString(m) } func (m *EntityInfoArgs) String() string { return proto.CompactTextString(m) }
func (*EntityInfoArgs) ProtoMessage() {} func (*EntityInfoArgs) ProtoMessage() {}
func (*EntityInfoArgs) Descriptor() ([]byte, []int) { func (*EntityInfoArgs) Descriptor() ([]byte, []int) {
return fileDescriptor_4dbf1dfe0c11846b, []int{42} return fileDescriptor_4dbf1dfe0c11846b, []int{40}
} }
func (m *EntityInfoArgs) XXX_Unmarshal(b []byte) error { func (m *EntityInfoArgs) XXX_Unmarshal(b []byte) error {
@ -2619,7 +2533,7 @@ func (m *EntityInfoReply) Reset() { *m = EntityInfoReply{} }
func (m *EntityInfoReply) String() string { return proto.CompactTextString(m) } func (m *EntityInfoReply) String() string { return proto.CompactTextString(m) }
func (*EntityInfoReply) ProtoMessage() {} func (*EntityInfoReply) ProtoMessage() {}
func (*EntityInfoReply) Descriptor() ([]byte, []int) { func (*EntityInfoReply) Descriptor() ([]byte, []int) {
return fileDescriptor_4dbf1dfe0c11846b, []int{43} return fileDescriptor_4dbf1dfe0c11846b, []int{41}
} }
func (m *EntityInfoReply) XXX_Unmarshal(b []byte) error { func (m *EntityInfoReply) XXX_Unmarshal(b []byte) error {
@ -2666,7 +2580,7 @@ func (m *PluginEnvReply) Reset() { *m = PluginEnvReply{} }
func (m *PluginEnvReply) String() string { return proto.CompactTextString(m) } func (m *PluginEnvReply) String() string { return proto.CompactTextString(m) }
func (*PluginEnvReply) ProtoMessage() {} func (*PluginEnvReply) ProtoMessage() {}
func (*PluginEnvReply) Descriptor() ([]byte, []int) { func (*PluginEnvReply) Descriptor() ([]byte, []int) {
return fileDescriptor_4dbf1dfe0c11846b, []int{44} return fileDescriptor_4dbf1dfe0c11846b, []int{42}
} }
func (m *PluginEnvReply) XXX_Unmarshal(b []byte) error { func (m *PluginEnvReply) XXX_Unmarshal(b []byte) error {
@ -2713,7 +2627,7 @@ func (m *Connection) Reset() { *m = Connection{} }
func (m *Connection) String() string { return proto.CompactTextString(m) } func (m *Connection) String() string { return proto.CompactTextString(m) }
func (*Connection) ProtoMessage() {} func (*Connection) ProtoMessage() {}
func (*Connection) Descriptor() ([]byte, []int) { func (*Connection) Descriptor() ([]byte, []int) {
return fileDescriptor_4dbf1dfe0c11846b, []int{45} return fileDescriptor_4dbf1dfe0c11846b, []int{43}
} }
func (m *Connection) XXX_Unmarshal(b []byte) error { func (m *Connection) XXX_Unmarshal(b []byte) error {
@ -2780,8 +2694,6 @@ func init() {
proto.RegisterType((*StorageDeleteArgs)(nil), "pb.StorageDeleteArgs") proto.RegisterType((*StorageDeleteArgs)(nil), "pb.StorageDeleteArgs")
proto.RegisterType((*StorageDeleteReply)(nil), "pb.StorageDeleteReply") proto.RegisterType((*StorageDeleteReply)(nil), "pb.StorageDeleteReply")
proto.RegisterType((*TTLReply)(nil), "pb.TTLReply") proto.RegisterType((*TTLReply)(nil), "pb.TTLReply")
proto.RegisterType((*SudoPrivilegeArgs)(nil), "pb.SudoPrivilegeArgs")
proto.RegisterType((*SudoPrivilegeReply)(nil), "pb.SudoPrivilegeReply")
proto.RegisterType((*TaintedReply)(nil), "pb.TaintedReply") proto.RegisterType((*TaintedReply)(nil), "pb.TaintedReply")
proto.RegisterType((*CachingDisabledReply)(nil), "pb.CachingDisabledReply") proto.RegisterType((*CachingDisabledReply)(nil), "pb.CachingDisabledReply")
proto.RegisterType((*ReplicationStateReply)(nil), "pb.ReplicationStateReply") proto.RegisterType((*ReplicationStateReply)(nil), "pb.ReplicationStateReply")
@ -2798,167 +2710,164 @@ func init() {
func init() { proto.RegisterFile("sdk/plugin/pb/backend.proto", fileDescriptor_4dbf1dfe0c11846b) } func init() { proto.RegisterFile("sdk/plugin/pb/backend.proto", fileDescriptor_4dbf1dfe0c11846b) }
var fileDescriptor_4dbf1dfe0c11846b = []byte{ var fileDescriptor_4dbf1dfe0c11846b = []byte{
// 2556 bytes of a gzipped FileDescriptorProto // 2504 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x59, 0x4b, 0x73, 0xe3, 0xc6, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x59, 0xcd, 0x72, 0x1b, 0xc7,
0x11, 0x2e, 0x92, 0xe2, 0xab, 0xf9, 0x9e, 0x95, 0x37, 0x58, 0xee, 0x3a, 0x2b, 0xc3, 0xd9, 0x35, 0x11, 0x2e, 0x00, 0xc4, 0x5f, 0xe3, 0x7f, 0x48, 0x2b, 0x2b, 0x48, 0x8e, 0xe8, 0x75, 0x24, 0xd3,
0xad, 0xd8, 0x94, 0x57, 0x1b, 0xc7, 0xeb, 0xa4, 0xec, 0x94, 0xac, 0x95, 0xd7, 0x8a, 0x25, 0x5b, 0x8c, 0x0d, 0x5a, 0x54, 0x14, 0xcb, 0x49, 0x25, 0x29, 0x9a, 0xa2, 0x65, 0xc6, 0xa4, 0xcd, 0x5a,
0x05, 0xd1, 0x71, 0x5e, 0x55, 0xf4, 0x10, 0x18, 0x51, 0x28, 0x81, 0x00, 0x32, 0x18, 0x68, 0xc5, 0x42, 0x71, 0xfe, 0xaa, 0xe0, 0xc1, 0xee, 0x10, 0xdc, 0xe2, 0x62, 0x77, 0x33, 0x3b, 0x4b, 0x11,
0x5c, 0xf2, 0x2f, 0xf2, 0x0f, 0x72, 0xce, 0x35, 0xb7, 0xdc, 0x52, 0xae, 0xdc, 0xf3, 0x17, 0xf2, 0xb9, 0xe4, 0x96, 0x47, 0xc8, 0x1b, 0xe4, 0x9c, 0x6b, 0x6e, 0xb9, 0xba, 0x72, 0xcf, 0x2b, 0xe4,
0x3b, 0x52, 0xd3, 0x33, 0x78, 0x91, 0x94, 0x1f, 0x55, 0xce, 0x6d, 0xa6, 0xbb, 0xe7, 0xd5, 0xf3, 0x39, 0x52, 0xd3, 0x33, 0xfb, 0x07, 0x80, 0xb6, 0x5c, 0xe5, 0xdc, 0x76, 0xba, 0x7b, 0x7a, 0x66,
0xf5, 0xd7, 0x3d, 0x00, 0xdc, 0x8f, 0x9c, 0xab, 0xbd, 0xd0, 0x8b, 0xe7, 0xae, 0xbf, 0x17, 0xce, 0x7a, 0xbe, 0xfe, 0xba, 0x07, 0x80, 0x7b, 0x91, 0x73, 0xb5, 0x17, 0x7a, 0xf1, 0xcc, 0xf5, 0xf7,
0xf6, 0x66, 0xd4, 0xbe, 0x62, 0xbe, 0x33, 0x0e, 0x79, 0x20, 0x02, 0x52, 0x0e, 0x67, 0xc3, 0x87, 0xc2, 0xe9, 0xde, 0x94, 0xda, 0x57, 0xcc, 0x77, 0x46, 0x21, 0x0f, 0x44, 0x40, 0xca, 0xe1, 0x74,
0xf3, 0x20, 0x98, 0x7b, 0x6c, 0x0f, 0x25, 0xb3, 0xf8, 0x62, 0x4f, 0xb8, 0x0b, 0x16, 0x09, 0xba, 0xf8, 0x60, 0x16, 0x04, 0x33, 0x8f, 0xed, 0xa1, 0x64, 0x1a, 0x5f, 0xec, 0x09, 0x77, 0xce, 0x22,
0x08, 0x95, 0xd1, 0x70, 0x28, 0x67, 0xf0, 0x82, 0xb9, 0x6b, 0x53, 0x6f, 0xcf, 0x75, 0x98, 0x2f, 0x41, 0xe7, 0xa1, 0x32, 0x1a, 0x0e, 0xa5, 0x07, 0x2f, 0x98, 0xb9, 0x36, 0xf5, 0xf6, 0x5c, 0x87,
0x5c, 0xb1, 0xd4, 0x3a, 0x23, 0xaf, 0x53, 0xab, 0x28, 0x8d, 0x59, 0x87, 0xea, 0xd1, 0x22, 0x14, 0xf9, 0xc2, 0x15, 0x0b, 0xad, 0x33, 0xf2, 0x3a, 0xb5, 0x8a, 0xd2, 0x98, 0x75, 0xa8, 0x1e, 0xcd,
0x4b, 0x73, 0x07, 0x6a, 0x9f, 0x30, 0xea, 0x30, 0x4e, 0xee, 0x42, 0xed, 0x12, 0x5b, 0x46, 0x69, 0x43, 0xb1, 0x30, 0xb7, 0xa1, 0xf6, 0x29, 0xa3, 0x0e, 0xe3, 0xe4, 0x0e, 0xd4, 0x2e, 0xf1, 0xcb,
0xa7, 0x32, 0x6a, 0x5a, 0xba, 0x67, 0xfe, 0x01, 0xe0, 0x4c, 0x8e, 0x39, 0xe2, 0x3c, 0xe0, 0xe4, 0x28, 0x6d, 0x57, 0x76, 0x9a, 0x96, 0x1e, 0x99, 0x7f, 0x00, 0x38, 0x93, 0x73, 0x8e, 0x38, 0x0f,
0x1e, 0x34, 0x18, 0xe7, 0x53, 0xb1, 0x0c, 0x99, 0x51, 0xda, 0x29, 0x8d, 0x3a, 0x56, 0x9d, 0x71, 0x38, 0xb9, 0x0b, 0x0d, 0xc6, 0xf9, 0x44, 0x2c, 0x42, 0x66, 0x94, 0xb6, 0x4b, 0x3b, 0x1d, 0xab,
0x3e, 0x59, 0x86, 0x8c, 0xfc, 0x08, 0x64, 0x73, 0xba, 0x88, 0xe6, 0x46, 0x79, 0xa7, 0x24, 0x67, 0xce, 0x38, 0x1f, 0x2f, 0x42, 0x46, 0x7e, 0x00, 0xf2, 0x73, 0x32, 0x8f, 0x66, 0x46, 0x79, 0xbb,
0x60, 0x9c, 0x9f, 0x46, 0xf3, 0x64, 0x8c, 0x1d, 0x38, 0xcc, 0xa8, 0xec, 0x94, 0x46, 0x15, 0x1c, 0x24, 0x3d, 0x30, 0xce, 0x4f, 0xa3, 0x59, 0x32, 0xc7, 0x0e, 0x1c, 0x66, 0x54, 0xb6, 0x4b, 0x3b,
0x73, 0x18, 0x38, 0xcc, 0xfc, 0x6b, 0x09, 0xaa, 0x67, 0x54, 0x5c, 0x46, 0x84, 0xc0, 0x16, 0x0f, 0x15, 0x9c, 0x73, 0x18, 0x38, 0xcc, 0xfc, 0x5b, 0x09, 0xaa, 0x67, 0x54, 0x5c, 0x46, 0x84, 0xc0,
0x02, 0xa1, 0x17, 0xc7, 0x36, 0x19, 0x41, 0x2f, 0xf6, 0x69, 0x2c, 0x2e, 0xe5, 0xa9, 0x6c, 0x2a, 0x06, 0x0f, 0x02, 0xa1, 0x17, 0xc7, 0x6f, 0xb2, 0x03, 0xbd, 0xd8, 0xa7, 0xb1, 0xb8, 0x94, 0xa7,
0x98, 0x63, 0x94, 0x51, 0xbd, 0x2a, 0x26, 0xaf, 0x43, 0xc7, 0x0b, 0x6c, 0xea, 0x4d, 0x23, 0x11, 0xb2, 0xa9, 0x60, 0x8e, 0x51, 0x46, 0xf5, 0xb2, 0x98, 0xbc, 0x0d, 0x1d, 0x2f, 0xb0, 0xa9, 0x37,
0x70, 0x3a, 0x97, 0xeb, 0x48, 0xbb, 0x36, 0x0a, 0xcf, 0x95, 0x8c, 0xec, 0xc2, 0x20, 0x62, 0xd4, 0x89, 0x44, 0xc0, 0xe9, 0x4c, 0xae, 0x23, 0xed, 0xda, 0x28, 0x3c, 0x57, 0x32, 0xb2, 0x0b, 0x83,
0x9b, 0xbe, 0xe4, 0x34, 0x4c, 0x0d, 0xb7, 0xd4, 0x84, 0x52, 0xf1, 0x25, 0xa7, 0xa1, 0xb6, 0x35, 0x88, 0x51, 0x6f, 0xf2, 0x8a, 0xd3, 0x30, 0x35, 0xdc, 0x50, 0x0e, 0xa5, 0xe2, 0x4b, 0x4e, 0x43,
0xff, 0x59, 0x83, 0xba, 0xc5, 0xfe, 0x14, 0xb3, 0x48, 0x90, 0x2e, 0x94, 0x5d, 0x07, 0x4f, 0xdb, 0x6d, 0x6b, 0xfe, 0xab, 0x06, 0x75, 0x8b, 0xfd, 0x29, 0x66, 0x91, 0x20, 0x5d, 0x28, 0xbb, 0x0e,
0xb4, 0xca, 0xae, 0x43, 0xc6, 0x40, 0x2c, 0x16, 0x7a, 0x72, 0x69, 0x37, 0xf0, 0x0f, 0xbd, 0x38, 0x9e, 0xb6, 0x69, 0x95, 0x5d, 0x87, 0x8c, 0x80, 0x58, 0x2c, 0xf4, 0xe4, 0xd2, 0x6e, 0xe0, 0x1f,
0x12, 0x8c, 0xeb, 0x33, 0x6f, 0xd0, 0x90, 0x07, 0xd0, 0x0c, 0x42, 0xc6, 0x51, 0x86, 0x0e, 0x68, 0x7a, 0x71, 0x24, 0x18, 0xd7, 0x67, 0x5e, 0xa3, 0x21, 0xf7, 0xa1, 0x19, 0x84, 0x8c, 0xa3, 0x0c,
0x5a, 0x99, 0x40, 0x1e, 0x3c, 0xa4, 0xe2, 0xd2, 0xd8, 0x42, 0x05, 0xb6, 0xa5, 0xcc, 0xa1, 0x82, 0x03, 0xd0, 0xb4, 0x32, 0x81, 0x3c, 0x78, 0x48, 0xc5, 0xa5, 0xb1, 0x81, 0x0a, 0xfc, 0x96, 0x32,
0x1a, 0x55, 0x25, 0x93, 0x6d, 0x62, 0x42, 0x2d, 0x62, 0x36, 0x67, 0xc2, 0xa8, 0xed, 0x94, 0x46, 0x87, 0x0a, 0x6a, 0x54, 0x95, 0x4c, 0x7e, 0x13, 0x13, 0x6a, 0x11, 0xb3, 0x39, 0x13, 0x46, 0x6d,
0xad, 0x7d, 0x18, 0x87, 0xb3, 0xf1, 0x39, 0x4a, 0x2c, 0xad, 0x21, 0x0f, 0x60, 0x4b, 0xfa, 0xc5, 0xbb, 0xb4, 0xd3, 0xda, 0x87, 0x51, 0x38, 0x1d, 0x9d, 0xa3, 0xc4, 0xd2, 0x1a, 0x72, 0x1f, 0x36,
0xa8, 0xa3, 0x45, 0x43, 0x5a, 0x1c, 0xc4, 0xe2, 0xd2, 0x42, 0x29, 0xd9, 0x87, 0xba, 0xba, 0xd3, 0x64, 0x5c, 0x8c, 0x3a, 0x5a, 0x34, 0xa4, 0xc5, 0x41, 0x2c, 0x2e, 0x2d, 0x94, 0x92, 0x7d, 0xa8,
0xc8, 0x68, 0xec, 0x54, 0x46, 0xad, 0x7d, 0x43, 0x1a, 0xe8, 0x53, 0x8e, 0x15, 0x0c, 0xa2, 0x23, 0xab, 0x3b, 0x8d, 0x8c, 0xc6, 0x76, 0x65, 0xa7, 0xb5, 0x6f, 0x48, 0x03, 0x7d, 0xca, 0x91, 0x82,
0x5f, 0xf0, 0xa5, 0x95, 0x18, 0x92, 0xd7, 0xa0, 0x6d, 0x7b, 0x2e, 0xf3, 0xc5, 0x54, 0x04, 0x57, 0x41, 0x74, 0xe4, 0x0b, 0xbe, 0xb0, 0x12, 0x43, 0xf2, 0x16, 0xb4, 0x6d, 0xcf, 0x65, 0xbe, 0x98,
0xcc, 0x37, 0x9a, 0xb8, 0xa3, 0x96, 0x92, 0x4d, 0xa4, 0x88, 0xec, 0xc3, 0x2b, 0x79, 0x93, 0x29, 0x88, 0xe0, 0x8a, 0xf9, 0x46, 0x13, 0x77, 0xd4, 0x52, 0xb2, 0xb1, 0x14, 0x91, 0x7d, 0x78, 0x23,
0xb5, 0x6d, 0x16, 0x45, 0x01, 0x37, 0x00, 0x6d, 0xef, 0xe4, 0x6c, 0x0f, 0xb4, 0x4a, 0x4e, 0xeb, 0x6f, 0x32, 0xa1, 0xb6, 0xcd, 0xa2, 0x28, 0xe0, 0x06, 0xa0, 0xed, 0x66, 0xce, 0xf6, 0x40, 0xab,
0xb8, 0x51, 0xe8, 0xd1, 0xe5, 0xd4, 0xa7, 0x0b, 0x66, 0xb4, 0xd4, 0xb4, 0x5a, 0xf6, 0x19, 0x5d, 0xa4, 0x5b, 0xc7, 0x8d, 0x42, 0x8f, 0x2e, 0x26, 0x3e, 0x9d, 0x33, 0xa3, 0xa5, 0xdc, 0x6a, 0xd9,
0x30, 0xf2, 0x10, 0x5a, 0x8b, 0x20, 0xf6, 0xc5, 0x34, 0x0c, 0x5c, 0x5f, 0x18, 0x6d, 0xb4, 0x00, 0xe7, 0x74, 0xce, 0xc8, 0x03, 0x68, 0xcd, 0x83, 0xd8, 0x17, 0x93, 0x30, 0x70, 0x7d, 0x61, 0xb4,
0x14, 0x9d, 0x49, 0x09, 0x79, 0x15, 0x54, 0x4f, 0x81, 0xb1, 0xa3, 0xfc, 0x8a, 0x12, 0x84, 0xe3, 0xd1, 0x02, 0x50, 0x74, 0x26, 0x25, 0xe4, 0x4d, 0x50, 0x23, 0x05, 0xc6, 0x8e, 0x8a, 0x2b, 0x4a,
0x23, 0xe8, 0x2a, 0x75, 0xba, 0x9f, 0x2e, 0x9a, 0x74, 0x50, 0x9a, 0xee, 0xe4, 0x1d, 0x68, 0x22, 0x10, 0x8e, 0x0f, 0xa1, 0xab, 0xd4, 0xe9, 0x7e, 0xba, 0x68, 0xd2, 0x41, 0x69, 0xba, 0x93, 0x0f,
0x1e, 0x5c, 0xff, 0x22, 0x30, 0x7a, 0xe8, 0xb7, 0x3b, 0x39, 0xb7, 0x48, 0x4c, 0x1c, 0xfb, 0x17, 0xa0, 0x89, 0x78, 0x70, 0xfd, 0x8b, 0xc0, 0xe8, 0x61, 0xdc, 0x36, 0x73, 0x61, 0x91, 0x98, 0x38,
0x81, 0xd5, 0x78, 0xa9, 0x5b, 0xe4, 0x03, 0xb8, 0x5f, 0x38, 0x2f, 0x67, 0x0b, 0xea, 0xfa, 0xae, 0xf6, 0x2f, 0x02, 0xab, 0xf1, 0x4a, 0x7f, 0x91, 0x5f, 0xc0, 0xbd, 0xc2, 0x79, 0x39, 0x9b, 0x53,
0x3f, 0x9f, 0xc6, 0x11, 0x8b, 0x8c, 0x3e, 0x22, 0xdc, 0xc8, 0x9d, 0xda, 0x4a, 0x0c, 0xbe, 0x88, 0xd7, 0x77, 0xfd, 0xd9, 0x24, 0x8e, 0x58, 0x64, 0xf4, 0x11, 0xe1, 0x46, 0xee, 0xd4, 0x56, 0x62,
0x58, 0x44, 0xee, 0x43, 0x53, 0x05, 0xe9, 0xd4, 0x75, 0x8c, 0x01, 0x6e, 0xa9, 0xa1, 0x04, 0xc7, 0xf0, 0x32, 0x62, 0x11, 0xb9, 0x07, 0x4d, 0x95, 0xa4, 0x13, 0xd7, 0x31, 0x06, 0xb8, 0xa5, 0x86,
0x0e, 0x79, 0x03, 0x7a, 0x61, 0xe0, 0xb9, 0xf6, 0x72, 0x1a, 0x5c, 0x33, 0xce, 0x5d, 0x87, 0x19, 0x12, 0x1c, 0x3b, 0xe4, 0x1d, 0xe8, 0x85, 0x81, 0xe7, 0xda, 0x8b, 0x49, 0x70, 0xcd, 0x38, 0x77,
0x64, 0xa7, 0x34, 0x6a, 0x58, 0x5d, 0x25, 0xfe, 0x5c, 0x4b, 0x37, 0x85, 0xc6, 0x1d, 0x34, 0x5c, 0x1d, 0x66, 0x90, 0xed, 0xd2, 0x4e, 0xc3, 0xea, 0x2a, 0xf1, 0x17, 0x5a, 0xba, 0x2e, 0x35, 0x36,
0x0b, 0x8d, 0x31, 0x80, 0x1d, 0xf8, 0x3e, 0xb3, 0x11, 0x7e, 0xdb, 0x78, 0xc2, 0xae, 0x3c, 0xe1, 0xd1, 0x70, 0x25, 0x35, 0x46, 0x00, 0x76, 0xe0, 0xfb, 0xcc, 0x46, 0xf8, 0x6d, 0xe1, 0x09, 0xbb,
0x61, 0x2a, 0xb5, 0x72, 0x16, 0xc3, 0x8f, 0xa1, 0x9d, 0x87, 0x02, 0xe9, 0x43, 0xe5, 0x8a, 0x2d, 0xf2, 0x84, 0x87, 0xa9, 0xd4, 0xca, 0x59, 0x0c, 0x3f, 0x81, 0x76, 0x1e, 0x0a, 0xa4, 0x0f, 0x95,
0x35, 0xfc, 0x65, 0x93, 0xec, 0x40, 0xf5, 0x9a, 0x7a, 0x31, 0x43, 0xc8, 0x6b, 0x20, 0xaa, 0x21, 0x2b, 0xb6, 0xd0, 0xf0, 0x97, 0x9f, 0x64, 0x1b, 0xaa, 0xd7, 0xd4, 0x8b, 0x19, 0x42, 0x5e, 0x03,
0x96, 0x52, 0xfc, 0xa2, 0xfc, 0xac, 0x64, 0xfe, 0xb7, 0x0a, 0x5b, 0x12, 0x7c, 0xe4, 0x5d, 0xe8, 0x51, 0x4d, 0xb1, 0x94, 0xe2, 0x67, 0xe5, 0x67, 0x25, 0xf3, 0xbf, 0x55, 0xd8, 0x90, 0xe0, 0x23,
0x78, 0x8c, 0x46, 0x6c, 0x1a, 0x84, 0x72, 0x81, 0x08, 0xa7, 0x6a, 0xed, 0xf7, 0xe5, 0xb0, 0x13, 0x4f, 0xa1, 0xe3, 0x31, 0x1a, 0xb1, 0x49, 0x10, 0xca, 0x05, 0x22, 0x74, 0xd5, 0xda, 0xef, 0xcb,
0xa9, 0xf8, 0x5c, 0xc9, 0xad, 0xb6, 0x97, 0xeb, 0xc9, 0x90, 0x76, 0x7d, 0xc1, 0xb8, 0x4f, 0xbd, 0x69, 0x27, 0x52, 0xf1, 0x85, 0x92, 0x5b, 0x6d, 0x2f, 0x37, 0x92, 0x29, 0xed, 0xfa, 0x82, 0x71,
0x29, 0x06, 0x83, 0x0a, 0xb0, 0x76, 0x22, 0x7c, 0x2e, 0x83, 0x62, 0x15, 0x47, 0x95, 0x75, 0x1c, 0x9f, 0x7a, 0x13, 0x4c, 0x06, 0x95, 0x60, 0xed, 0x44, 0xf8, 0x5c, 0x26, 0xc5, 0x32, 0x8e, 0x2a,
0x0d, 0xa1, 0x81, 0xbe, 0x73, 0x59, 0xa4, 0x83, 0x3d, 0xed, 0x93, 0x7d, 0x68, 0x2c, 0x98, 0xa0, 0xab, 0x38, 0x1a, 0x42, 0x03, 0x63, 0xe7, 0xb2, 0x48, 0x27, 0x7b, 0x3a, 0x26, 0xfb, 0xd0, 0x98,
0x3a, 0xd6, 0x64, 0x48, 0xdc, 0x4d, 0x62, 0x66, 0x7c, 0xaa, 0x15, 0x2a, 0x20, 0x52, 0xbb, 0xb5, 0x33, 0x41, 0x75, 0xae, 0xc9, 0x94, 0xb8, 0x93, 0xe4, 0xcc, 0xe8, 0x54, 0x2b, 0x54, 0x42, 0xa4,
0x88, 0xa8, 0xad, 0x47, 0xc4, 0x10, 0x1a, 0x29, 0xe8, 0xea, 0xea, 0x86, 0x93, 0xbe, 0xa4, 0xd9, 0x76, 0x2b, 0x19, 0x51, 0x5b, 0xcd, 0x88, 0x21, 0x34, 0x52, 0xd0, 0xd5, 0xd5, 0x0d, 0x27, 0x63,
0x90, 0x71, 0x37, 0x70, 0x8c, 0x06, 0x02, 0x45, 0xf7, 0x24, 0x49, 0xfa, 0xf1, 0x42, 0x41, 0xa8, 0x49, 0xb3, 0x21, 0xe3, 0x6e, 0xe0, 0x18, 0x0d, 0x04, 0x8a, 0x1e, 0x49, 0x92, 0xf4, 0xe3, 0xb9,
0xa9, 0x48, 0xd2, 0x8f, 0x17, 0xeb, 0x88, 0x81, 0x15, 0xc4, 0xfc, 0x04, 0xaa, 0xd4, 0x73, 0x69, 0x82, 0x50, 0x53, 0x91, 0xa4, 0x1f, 0xcf, 0x57, 0x11, 0x03, 0x4b, 0x88, 0xf9, 0x11, 0x54, 0xa9,
0x84, 0x21, 0x24, 0x6f, 0x56, 0xf3, 0xfd, 0xf8, 0x40, 0x4a, 0x2d, 0xa5, 0x24, 0x4f, 0xa1, 0x33, 0xe7, 0xd2, 0x08, 0x53, 0x48, 0xde, 0xac, 0xe6, 0xfb, 0xd1, 0x81, 0x94, 0x5a, 0x4a, 0x49, 0x9e,
0xe7, 0x41, 0x1c, 0x4e, 0xb1, 0xcb, 0x22, 0xa3, 0x8d, 0xa7, 0x5d, 0xb5, 0x6e, 0xa3, 0xd1, 0x81, 0x40, 0x67, 0xc6, 0x83, 0x38, 0x9c, 0xe0, 0x90, 0x45, 0x46, 0x1b, 0x4f, 0xbb, 0x6c, 0xdd, 0x46,
0xb2, 0x91, 0x11, 0x38, 0x0b, 0x62, 0xdf, 0x99, 0xda, 0xae, 0xc3, 0x23, 0xa3, 0x83, 0xce, 0x03, 0xa3, 0x03, 0x65, 0x23, 0x33, 0x70, 0x1a, 0xc4, 0xbe, 0x33, 0xb1, 0x5d, 0x87, 0x47, 0x46, 0x07,
0x14, 0x1d, 0x4a, 0x89, 0x0c, 0x31, 0x15, 0x02, 0xa9, 0x83, 0xbb, 0x68, 0xd3, 0x41, 0xe9, 0x59, 0x83, 0x07, 0x28, 0x3a, 0x94, 0x12, 0x99, 0x62, 0x2a, 0x05, 0xd2, 0x00, 0x77, 0xd1, 0xa6, 0x83,
0xe2, 0xe5, 0x9f, 0xc2, 0x20, 0x49, 0x4c, 0x99, 0x65, 0x0f, 0x2d, 0xfb, 0x89, 0x22, 0x35, 0x1e, 0xd2, 0xb3, 0x24, 0xca, 0x3f, 0x86, 0x41, 0x52, 0x98, 0x32, 0xcb, 0x1e, 0x5a, 0xf6, 0x13, 0x45,
0x41, 0x9f, 0xdd, 0x48, 0x0a, 0x75, 0xc5, 0x74, 0x41, 0x6f, 0xa6, 0x42, 0x78, 0x3a, 0xa4, 0xba, 0x6a, 0xbc, 0x03, 0x7d, 0x76, 0x23, 0x29, 0xd4, 0x15, 0x93, 0x39, 0xbd, 0x99, 0x08, 0xe1, 0xe9,
0x89, 0xfc, 0x94, 0xde, 0x4c, 0x84, 0x27, 0xe3, 0x5f, 0xad, 0x8e, 0xf1, 0x3f, 0xc0, 0x64, 0xd4, 0x94, 0xea, 0x26, 0xf2, 0x53, 0x7a, 0x33, 0x16, 0x9e, 0xcc, 0x7f, 0xb5, 0x3a, 0xe6, 0xff, 0x00,
0x44, 0x09, 0xc6, 0xff, 0x2e, 0x0c, 0xfc, 0x60, 0xea, 0xb0, 0x0b, 0x1a, 0x7b, 0x42, 0xad, 0xbb, 0x8b, 0x51, 0x13, 0x25, 0x98, 0xff, 0xbb, 0x30, 0xf0, 0x83, 0x89, 0xc3, 0x2e, 0x68, 0xec, 0x09,
0xd4, 0xc1, 0xd4, 0xf3, 0x83, 0xe7, 0x4a, 0x8e, 0xcb, 0x2e, 0x87, 0xbf, 0x84, 0x4e, 0xe1, 0xba, 0xb5, 0xee, 0x42, 0x27, 0x53, 0xcf, 0x0f, 0x9e, 0x2b, 0x39, 0x2e, 0xbb, 0x18, 0xfe, 0x1c, 0x3a,
0x37, 0x80, 0x7e, 0x3b, 0x0f, 0xfa, 0x66, 0x1e, 0xe8, 0xff, 0xde, 0x02, 0xc0, 0x7b, 0x57, 0x43, 0x85, 0xeb, 0x5e, 0x03, 0xfa, 0xad, 0x3c, 0xe8, 0x9b, 0x79, 0xa0, 0xff, 0x7b, 0x03, 0x00, 0xef,
0x57, 0xb3, 0x45, 0x1e, 0x0c, 0xe5, 0x0d, 0x60, 0xa0, 0x9c, 0xf9, 0x42, 0x03, 0x57, 0xf7, 0xbe, 0x5d, 0x4d, 0x5d, 0xae, 0x16, 0x79, 0x30, 0x94, 0xd7, 0x80, 0x81, 0x72, 0xe6, 0x0b, 0x0d, 0x5c,
0x11, 0xb3, 0x49, 0xbe, 0xa8, 0xe6, 0xf2, 0xc5, 0x5b, 0xb0, 0x25, 0xf1, 0x69, 0xd4, 0x32, 0x5a, 0x3d, 0xfa, 0x46, 0xcc, 0x26, 0xf5, 0xa2, 0x9a, 0xab, 0x17, 0xef, 0xc1, 0x86, 0xc4, 0xa7, 0x51,
0xcf, 0x76, 0x84, 0x48, 0x56, 0x28, 0x46, 0xab, 0xb5, 0xa0, 0xa9, 0xaf, 0x07, 0x4d, 0x1e, 0x8d, 0xcb, 0x68, 0x3d, 0xdb, 0x11, 0x22, 0x59, 0xa1, 0x18, 0xad, 0x56, 0x92, 0xa6, 0xbe, 0x9a, 0x34,
0x8d, 0x22, 0x1a, 0x5f, 0x87, 0x8e, 0xcd, 0x19, 0xe6, 0xae, 0xa9, 0x2c, 0x46, 0x34, 0x5a, 0xdb, 0x79, 0x34, 0x36, 0x8a, 0x68, 0x7c, 0x1b, 0x3a, 0x36, 0x67, 0x58, 0xbb, 0x26, 0xb2, 0x19, 0xd1,
0x89, 0x70, 0xe2, 0x2e, 0x98, 0xf4, 0x9f, 0xbc, 0x38, 0x40, 0x95, 0x6c, 0x6e, 0xbc, 0xd7, 0xd6, 0x68, 0x6d, 0x27, 0xc2, 0xb1, 0x3b, 0x67, 0x32, 0x7e, 0xf2, 0xe2, 0x00, 0x55, 0xf2, 0x73, 0xed,
0xc6, 0x7b, 0xc5, 0x4a, 0xc0, 0x63, 0x9a, 0xf1, 0xb1, 0x9d, 0x8b, 0x9a, 0x4e, 0x21, 0x6a, 0x0a, 0xbd, 0xb6, 0xd6, 0xde, 0x2b, 0x76, 0x02, 0x1e, 0xd3, 0x8c, 0x8f, 0xdf, 0xb9, 0xac, 0xe9, 0x14,
0xa1, 0xd1, 0x5d, 0x09, 0x8d, 0x15, 0xfc, 0xf6, 0xd6, 0xf0, 0xfb, 0x1a, 0xb4, 0xa5, 0x03, 0xa2, 0xb2, 0xa6, 0x90, 0x1a, 0xdd, 0xa5, 0xd4, 0x58, 0xc2, 0x6f, 0x6f, 0x05, 0xbf, 0x6f, 0x41, 0x5b,
0x90, 0xda, 0x4c, 0x4e, 0xd0, 0x57, 0x8e, 0x48, 0x65, 0xc7, 0x0e, 0x46, 0x7b, 0x3c, 0x9b, 0x2d, 0x06, 0x20, 0x0a, 0xa9, 0xcd, 0xa4, 0x83, 0xbe, 0x0a, 0x44, 0x2a, 0x3b, 0x76, 0x30, 0xdb, 0xe3,
0x2f, 0x03, 0x8f, 0x65, 0x84, 0xdd, 0x4a, 0x65, 0xc7, 0x8e, 0xdc, 0x2f, 0x22, 0x90, 0x20, 0x02, 0xe9, 0x74, 0x71, 0x19, 0x78, 0x2c, 0x23, 0xec, 0x56, 0x2a, 0x3b, 0x76, 0xe4, 0x7e, 0x11, 0x81,
0xb1, 0x3d, 0x7c, 0x0f, 0x9a, 0xa9, 0xd7, 0xbf, 0x17, 0x98, 0xfe, 0x5e, 0x82, 0x76, 0x9e, 0x14, 0x04, 0x11, 0x88, 0xdf, 0xc3, 0x0f, 0xa1, 0x99, 0x46, 0xfd, 0x3b, 0x81, 0xe9, 0x1f, 0x25, 0x68,
0xe5, 0xe0, 0xc9, 0xe4, 0x04, 0x07, 0x57, 0x2c, 0xd9, 0x94, 0xe5, 0x04, 0x67, 0x3e, 0x7b, 0x49, 0xe7, 0x49, 0x51, 0x4e, 0x1e, 0x8f, 0x4f, 0x70, 0x72, 0xc5, 0x92, 0x9f, 0xb2, 0x9d, 0xe0, 0xcc,
0x67, 0x9e, 0x9a, 0xa0, 0x61, 0x65, 0x02, 0xa9, 0x75, 0x7d, 0x9b, 0xb3, 0x45, 0x82, 0xaa, 0x8a, 0x67, 0xaf, 0xe8, 0xd4, 0x53, 0x0e, 0x1a, 0x56, 0x26, 0x90, 0x5a, 0xd7, 0xb7, 0x39, 0x9b, 0x27,
0x95, 0x09, 0xc8, 0xfb, 0x00, 0x6e, 0x14, 0xc5, 0x4c, 0xdd, 0xdc, 0x16, 0x52, 0xc6, 0x70, 0xac, 0xa8, 0xaa, 0x58, 0x99, 0x80, 0x7c, 0x04, 0xe0, 0x46, 0x51, 0xcc, 0xd4, 0xcd, 0x6d, 0x20, 0x65,
0x6a, 0xcc, 0x71, 0x52, 0x63, 0x8e, 0x27, 0x49, 0x8d, 0x69, 0x35, 0xd1, 0x1a, 0xaf, 0xf4, 0x2e, 0x0c, 0x47, 0xaa, 0xc7, 0x1c, 0x25, 0x3d, 0xe6, 0x68, 0x9c, 0xf4, 0x98, 0x56, 0x13, 0xad, 0xf1,
0xd4, 0xe4, 0x05, 0x4d, 0x4e, 0x10, 0x79, 0x15, 0x4b, 0xf7, 0xcc, 0xbf, 0x40, 0x4d, 0x55, 0x21, 0x4a, 0xef, 0x40, 0x4d, 0x5e, 0xd0, 0xf8, 0x04, 0x91, 0x57, 0xb1, 0xf4, 0xc8, 0xfc, 0x0b, 0xd4,
0xff, 0x57, 0xa2, 0xbf, 0x07, 0x0d, 0x35, 0xb7, 0xeb, 0xe8, 0x58, 0xa9, 0x63, 0xff, 0xd8, 0x31, 0x54, 0x17, 0xf2, 0x7f, 0x25, 0xfa, 0xbb, 0xd0, 0x50, 0xbe, 0x5d, 0x47, 0xe7, 0x4a, 0x1d, 0xc7,
0xbf, 0x2e, 0x43, 0xc3, 0x62, 0x51, 0x18, 0xf8, 0x11, 0xcb, 0x55, 0x49, 0xa5, 0x6f, 0xad, 0x92, 0xc7, 0x8e, 0xf9, 0x75, 0x19, 0x1a, 0x16, 0x8b, 0xc2, 0xc0, 0x8f, 0x58, 0xae, 0x4b, 0x2a, 0x7d,
0xca, 0x1b, 0xab, 0xa4, 0xa4, 0xf6, 0xaa, 0xe4, 0x6a, 0xaf, 0x21, 0x34, 0x38, 0x73, 0x5c, 0xce, 0x6b, 0x97, 0x54, 0x5e, 0xdb, 0x25, 0x25, 0xbd, 0x57, 0x25, 0xd7, 0x7b, 0x0d, 0xa1, 0xc1, 0x99,
0x6c, 0xa1, 0xeb, 0xb4, 0xb4, 0x2f, 0x75, 0x2f, 0x29, 0x97, 0xe9, 0x3d, 0xc2, 0x1c, 0xd2, 0xb4, 0xe3, 0x72, 0x66, 0x0b, 0xdd, 0xa7, 0xa5, 0x63, 0xa9, 0x7b, 0x45, 0xb9, 0x2c, 0xef, 0x11, 0xd6,
0xd2, 0x3e, 0x79, 0x92, 0x2f, 0x2e, 0x54, 0xd9, 0xb6, 0xad, 0x8a, 0x0b, 0xb5, 0xdd, 0x0d, 0xd5, 0x90, 0xa6, 0x95, 0x8e, 0xc9, 0xe3, 0x7c, 0x73, 0xa1, 0xda, 0xb6, 0x2d, 0xd5, 0x5c, 0xa8, 0xed,
0xc5, 0xd3, 0xac, 0x48, 0xab, 0x63, 0x34, 0xdf, 0xcb, 0x0f, 0xd8, 0x5c, 0xa5, 0xfd, 0x60, 0x39, 0xae, 0xe9, 0x2e, 0x9e, 0x64, 0x4d, 0x5a, 0x1d, 0xb3, 0xf9, 0x6e, 0x7e, 0xc2, 0xfa, 0x2e, 0xed,
0xfb, 0xeb, 0x32, 0xf4, 0x57, 0xf7, 0xb6, 0x01, 0x81, 0xdb, 0x50, 0x55, 0xb9, 0x4f, 0xc3, 0x57, 0x7b, 0xab, 0xd9, 0x5f, 0x97, 0xa1, 0xbf, 0xbc, 0xb7, 0x35, 0x08, 0xdc, 0x82, 0xaa, 0xaa, 0x7d,
0xac, 0x65, 0xbd, 0xca, 0x0a, 0xd1, 0xfd, 0x6a, 0x95, 0x34, 0xbe, 0x1d, 0x7a, 0x45, 0x42, 0x79, 0x1a, 0xbe, 0x62, 0xa5, 0xea, 0x55, 0x96, 0x88, 0xee, 0x57, 0xcb, 0xa4, 0xf1, 0xed, 0xd0, 0x2b,
0x13, 0xfa, 0xd2, 0x45, 0x21, 0x73, 0xb2, 0x7a, 0x4e, 0x31, 0x60, 0x4f, 0xcb, 0xd3, 0x8a, 0x6e, 0x12, 0xca, 0xbb, 0xd0, 0x97, 0x21, 0x0a, 0x99, 0x93, 0xf5, 0x73, 0x8a, 0x01, 0x7b, 0x5a, 0x9e,
0x17, 0x06, 0x89, 0x69, 0xc6, 0x0d, 0xb5, 0x82, 0xed, 0x51, 0x42, 0x11, 0x77, 0xa1, 0x76, 0x11, 0x76, 0x74, 0xbb, 0x30, 0x48, 0x4c, 0x33, 0x6e, 0xa8, 0x15, 0x6c, 0x8f, 0x12, 0x8a, 0xb8, 0x03,
0xf0, 0x05, 0x15, 0x9a, 0x04, 0x75, 0xaf, 0x40, 0x72, 0xc8, 0xb6, 0x0d, 0x85, 0xc9, 0x44, 0x28, 0xb5, 0x8b, 0x80, 0xcf, 0xa9, 0xd0, 0x24, 0xa8, 0x47, 0x05, 0x92, 0x43, 0xb6, 0x6d, 0x28, 0x4c,
0xdf, 0x2c, 0x92, 0x7c, 0xd2, 0xf7, 0x04, 0xb2, 0x60, 0xc3, 0x6a, 0x24, 0xef, 0x08, 0xf3, 0xb7, 0x26, 0x42, 0xf9, 0x66, 0x91, 0xe4, 0x93, 0xbe, 0x27, 0x90, 0x05, 0x1b, 0x56, 0x23, 0x79, 0x47,
0xd0, 0x5b, 0x29, 0x21, 0x37, 0x38, 0x32, 0x5b, 0xbe, 0x5c, 0x58, 0xbe, 0x30, 0x73, 0x65, 0x65, 0x98, 0xbf, 0x85, 0xde, 0x52, 0x0b, 0xb9, 0x26, 0x90, 0xd9, 0xf2, 0xe5, 0xc2, 0xf2, 0x05, 0xcf,
0xe6, 0xdf, 0xc1, 0xe0, 0x13, 0xea, 0x3b, 0x1e, 0xd3, 0xf3, 0x1f, 0xf0, 0x79, 0x24, 0x93, 0xa1, 0x95, 0x25, 0xcf, 0xbf, 0x83, 0xc1, 0xa7, 0xd4, 0x77, 0x3c, 0xa6, 0xfd, 0x1f, 0xf0, 0x59, 0x24,
0x7e, 0xd1, 0x4c, 0x75, 0xf6, 0xe9, 0x58, 0x4d, 0x2d, 0x39, 0x76, 0xc8, 0x23, 0xa8, 0x73, 0x65, 0x8b, 0xa1, 0x7e, 0xd1, 0x4c, 0x74, 0xf5, 0xe9, 0x58, 0x4d, 0x2d, 0x39, 0x76, 0xc8, 0x43, 0xa8,
0xad, 0x01, 0xd0, 0xca, 0xd5, 0xb8, 0x56, 0xa2, 0x33, 0xbf, 0x02, 0x52, 0x98, 0x5a, 0x3e, 0x66, 0x73, 0x65, 0xad, 0x01, 0xd0, 0xca, 0xf5, 0xb8, 0x56, 0xa2, 0x33, 0xbf, 0x02, 0x52, 0x70, 0x2d,
0x96, 0x64, 0x24, 0xd1, 0xaf, 0x40, 0xa1, 0xa3, 0xaa, 0x9d, 0xc7, 0xa4, 0x95, 0x6a, 0xc9, 0x0e, 0x1f, 0x33, 0x0b, 0xb2, 0x23, 0xd1, 0xaf, 0x40, 0xa1, 0xb3, 0xaa, 0x9d, 0xc7, 0xa4, 0x95, 0x6a,
0x54, 0x18, 0xe7, 0x7a, 0x09, 0x2c, 0x32, 0xb3, 0xa7, 0xa3, 0x25, 0x55, 0x66, 0x1f, 0xba, 0xc7, 0xc9, 0x36, 0x54, 0x18, 0xe7, 0x7a, 0x09, 0x6c, 0x32, 0xb3, 0xa7, 0xa3, 0x25, 0x55, 0x66, 0x1f,
0xbe, 0x2b, 0x5c, 0xea, 0xb9, 0x7f, 0x66, 0x72, 0xe7, 0xe6, 0x53, 0xe8, 0x65, 0x12, 0xb5, 0xa0, 0xba, 0xc7, 0xbe, 0x2b, 0x5c, 0xea, 0xb9, 0x7f, 0x66, 0x72, 0xe7, 0xe6, 0x13, 0xe8, 0x65, 0x12,
0x9e, 0xa6, 0x74, 0xfb, 0x34, 0x3f, 0x83, 0xc1, 0x79, 0xc8, 0x6c, 0x97, 0x7a, 0xf8, 0x7a, 0x54, 0xb5, 0xa0, 0x76, 0x53, 0xba, 0xdd, 0xcd, 0x4f, 0x60, 0x70, 0x1e, 0x32, 0xdb, 0xa5, 0x1e, 0xbe,
0xc3, 0x1e, 0x42, 0x55, 0xde, 0x55, 0xc2, 0x3b, 0x4d, 0x1c, 0x88, 0x6a, 0x25, 0x37, 0xbf, 0x02, 0x1e, 0xd5, 0xb4, 0x07, 0x50, 0x95, 0x77, 0x95, 0xf0, 0x4e, 0x13, 0x27, 0xa2, 0x5a, 0xc9, 0xcd,
0x43, 0x1d, 0xef, 0xe8, 0xc6, 0x8d, 0x04, 0xf3, 0x6d, 0x76, 0x78, 0xc9, 0xec, 0xab, 0x1f, 0xd0, 0xaf, 0xc0, 0x50, 0xc7, 0x3b, 0xba, 0x71, 0x23, 0xc1, 0x7c, 0x9b, 0x1d, 0x5e, 0x32, 0xfb, 0xea,
0x81, 0xd7, 0x70, 0x6f, 0xd3, 0x0a, 0xc9, 0xfe, 0x5a, 0xb6, 0xec, 0x4d, 0x2f, 0x64, 0x0a, 0xc2, 0x7b, 0x0c, 0xe0, 0x35, 0xdc, 0x5d, 0xb7, 0x42, 0xb2, 0xbf, 0x96, 0x2d, 0x47, 0x93, 0x0b, 0x59,
0x35, 0x1a, 0x16, 0xa0, 0xe8, 0x63, 0x29, 0x91, 0x70, 0x60, 0x72, 0x5c, 0xa4, 0x69, 0x5d, 0xf7, 0x82, 0x70, 0x8d, 0x86, 0x05, 0x28, 0xfa, 0x44, 0x4a, 0x24, 0x1c, 0x98, 0x9c, 0x17, 0x69, 0x5a,
0x12, 0x7f, 0x54, 0x6e, 0xf7, 0xc7, 0x3f, 0x4a, 0xd0, 0x3c, 0x67, 0x22, 0x0e, 0xf1, 0x2c, 0xf7, 0xd7, 0xa3, 0x24, 0x1e, 0x95, 0xdb, 0xe3, 0xf1, 0xcf, 0x12, 0x34, 0xcf, 0x99, 0x88, 0x43, 0x3c,
0xa1, 0x39, 0xe3, 0xc1, 0x15, 0xe3, 0xd9, 0x51, 0x1a, 0x4a, 0x70, 0xec, 0x90, 0x27, 0x50, 0x3b, 0xcb, 0x3d, 0x68, 0x4e, 0x79, 0x70, 0xc5, 0x78, 0x76, 0x94, 0x86, 0x12, 0x1c, 0x3b, 0xe4, 0x31,
0x0c, 0xfc, 0x0b, 0x77, 0x8e, 0x6f, 0x69, 0xcd, 0x2f, 0xe9, 0xd8, 0xb1, 0xd2, 0x29, 0x7e, 0xd1, 0xd4, 0x0e, 0x03, 0xff, 0xc2, 0x9d, 0xe1, 0x5b, 0x5a, 0xf3, 0x4b, 0x3a, 0x77, 0xa4, 0x74, 0x8a,
0x86, 0x64, 0x07, 0x5a, 0xfa, 0xcb, 0xc4, 0x17, 0x5f, 0x1c, 0x3f, 0x4f, 0x8a, 0xec, 0x9c, 0x68, 0x5f, 0xb4, 0x21, 0xd9, 0x86, 0x96, 0xfe, 0x65, 0xe2, 0xe5, 0xcb, 0xe3, 0xe7, 0x49, 0x93, 0x9d,
0xf8, 0x3e, 0xb4, 0x72, 0x03, 0xbf, 0x57, 0xc6, 0xfb, 0x31, 0x00, 0xae, 0xae, 0x7c, 0xd4, 0xcf, 0x13, 0x0d, 0x3f, 0x82, 0x56, 0x6e, 0xe2, 0x77, 0xaa, 0x78, 0x3f, 0x04, 0xc0, 0xd5, 0x55, 0x8c,
0xae, 0xbe, 0xa9, 0x8e, 0xf6, 0x10, 0x9a, 0xb2, 0x9e, 0x53, 0xea, 0x24, 0xd7, 0x96, 0xb2, 0x5c, 0xfa, 0xd9, 0xd5, 0x37, 0xd5, 0xd1, 0x1e, 0x40, 0x53, 0xf6, 0x73, 0x4a, 0x9d, 0xd4, 0xda, 0x52,
0x6b, 0x3e, 0x82, 0xc1, 0xb1, 0x7f, 0x4d, 0x3d, 0xd7, 0xa1, 0x82, 0x7d, 0xca, 0x96, 0xe8, 0x82, 0x56, 0x6b, 0xcd, 0x87, 0x30, 0x38, 0xf6, 0xaf, 0xa9, 0xe7, 0x3a, 0x54, 0xb0, 0xcf, 0xd8, 0x02,
0xb5, 0x1d, 0x98, 0xe7, 0xd0, 0xd6, 0x8f, 0xfb, 0xef, 0xb4, 0xc7, 0xb6, 0xde, 0xe3, 0x37, 0xc7, 0x43, 0xb0, 0xb2, 0x03, 0xf3, 0x1c, 0xda, 0xfa, 0x71, 0xff, 0x5a, 0x7b, 0x6c, 0xeb, 0x3d, 0x7e,
0xe2, 0x9b, 0xd0, 0xd3, 0x93, 0x9e, 0xb8, 0x3a, 0x12, 0x65, 0xa9, 0xc2, 0xd9, 0x85, 0x7b, 0xa3, 0x73, 0x2e, 0xbe, 0x0b, 0x3d, 0xed, 0xf4, 0xc4, 0xd5, 0x99, 0x28, 0x5b, 0x15, 0xce, 0x2e, 0xdc,
0xa7, 0xd6, 0x3d, 0xf3, 0x19, 0xf4, 0x73, 0xa6, 0xe9, 0x71, 0xae, 0xd8, 0x32, 0x4a, 0x3e, 0x7a, 0x1b, 0xed, 0x5a, 0x8f, 0xcc, 0x67, 0xd0, 0xcf, 0x99, 0xa6, 0xc7, 0xb9, 0x62, 0x8b, 0x28, 0xf9,
0xc8, 0x76, 0xe2, 0x81, 0x72, 0xe6, 0x01, 0x13, 0xba, 0x7a, 0xe4, 0x0b, 0x26, 0x6e, 0x39, 0xdd, 0xd1, 0x43, 0x7e, 0x27, 0x11, 0x28, 0x67, 0x11, 0x30, 0xa1, 0xab, 0x67, 0xbe, 0x60, 0xe2, 0x96,
0xa7, 0xe9, 0x46, 0x5e, 0x30, 0x3d, 0xf9, 0x63, 0xa8, 0x32, 0x79, 0xd2, 0x7c, 0x1a, 0xce, 0x7b, 0xd3, 0x7d, 0x96, 0x6e, 0xe4, 0x05, 0xd3, 0xce, 0x1f, 0x41, 0x95, 0xc9, 0x93, 0xe6, 0xcb, 0x70,
0xc0, 0x52, 0xea, 0x0d, 0x0b, 0x3e, 0x4b, 0x17, 0x3c, 0x8b, 0xd5, 0x82, 0xdf, 0x71, 0x2e, 0xf3, 0x3e, 0x02, 0x96, 0x52, 0xaf, 0x59, 0xf0, 0x59, 0xba, 0xe0, 0x59, 0xac, 0x16, 0x7c, 0x4d, 0x5f,
0xf5, 0x74, 0x1b, 0x67, 0xb1, 0xb8, 0xed, 0x46, 0x1f, 0xc1, 0x40, 0x1b, 0x3d, 0x67, 0x1e, 0x13, 0xe6, 0xdb, 0xe9, 0x36, 0xce, 0x62, 0x71, 0xdb, 0x8d, 0x3e, 0x84, 0x81, 0x36, 0x7a, 0xce, 0x3c,
0xec, 0x96, 0x23, 0x3d, 0x06, 0x52, 0x30, 0xbb, 0x6d, 0xba, 0x07, 0xd0, 0x98, 0x4c, 0x4e, 0x52, 0x26, 0xd8, 0x2d, 0x47, 0x7a, 0x04, 0xa4, 0x60, 0x76, 0x9b, 0xbb, 0xfb, 0xd0, 0x18, 0x8f, 0x4f,
0x6d, 0x91, 0x62, 0xcd, 0x0f, 0x60, 0x70, 0x1e, 0x3b, 0xc1, 0x19, 0x77, 0xaf, 0x5d, 0x8f, 0xcd, 0x52, 0x6d, 0x91, 0x62, 0xcd, 0x1d, 0x68, 0x8f, 0xa9, 0x6c, 0x25, 0x1c, 0x65, 0x61, 0x40, 0x5d,
0xd5, 0x62, 0x49, 0x0d, 0x5d, 0xca, 0xd5, 0xd0, 0x1b, 0x93, 0x9a, 0x39, 0x02, 0x52, 0x18, 0x9e, 0xa8, 0xb1, 0x4e, 0xc0, 0x64, 0x68, 0xee, 0xc3, 0xd6, 0x21, 0xb5, 0x2f, 0x5d, 0x7f, 0xf6, 0xdc,
0xde, 0x5b, 0x14, 0x3b, 0x81, 0x0e, 0x61, 0x6c, 0x9b, 0x23, 0x68, 0x4f, 0xa8, 0xac, 0x59, 0x1c, 0x8d, 0x64, 0x2f, 0xa5, 0x67, 0x0c, 0xa1, 0xe1, 0x68, 0x81, 0x9e, 0x92, 0x8e, 0xcd, 0xf7, 0xe1,
0x65, 0x63, 0x40, 0x5d, 0xa8, 0xbe, 0x36, 0x4b, 0xba, 0xe6, 0x3e, 0x6c, 0x1f, 0x52, 0xfb, 0xd2, 0x8d, 0xdc, 0x0f, 0x3e, 0xe7, 0x82, 0x26, 0xdb, 0xdc, 0x82, 0x6a, 0x24, 0x47, 0x38, 0xa3, 0x6a,
0xf5, 0xe7, 0xcf, 0xdd, 0x48, 0x16, 0x6d, 0x7a, 0xc4, 0x10, 0x1a, 0x8e, 0x16, 0xe8, 0x21, 0x69, 0xa9, 0x81, 0xf9, 0x39, 0x6c, 0xe5, 0xcb, 0xab, 0xec, 0x6c, 0xf0, 0xf0, 0x49, 0xcf, 0x51, 0xca,
0xdf, 0x7c, 0x1b, 0x5e, 0xc9, 0x7d, 0x59, 0x3a, 0x17, 0x34, 0xf1, 0xc7, 0x36, 0x54, 0x23, 0xd9, 0xf5, 0x1c, 0xfa, 0x28, 0xe5, 0xac, 0x5a, 0xf4, 0xa1, 0xf2, 0xeb, 0x2f, 0xc7, 0x1a, 0x83, 0xf2,
0xc3, 0x11, 0x55, 0x4b, 0x75, 0xcc, 0xcf, 0x60, 0x3b, 0x9f, 0xc7, 0x65, 0x09, 0x95, 0x1c, 0x1c, 0xd3, 0xfc, 0xa3, 0x5c, 0xbe, 0xe8, 0x4f, 0x2d, 0x5f, 0x68, 0x3c, 0x4a, 0xaf, 0xd5, 0x78, 0xac,
0x8b, 0x9b, 0x52, 0xae, 0xb8, 0xd1, 0x3e, 0x2b, 0x67, 0x69, 0xa9, 0x0f, 0x95, 0x5f, 0x7f, 0x39, 0xc2, 0xe0, 0x7d, 0x18, 0x9c, 0x7a, 0x81, 0x7d, 0x75, 0xe4, 0xe7, 0xa2, 0x61, 0x40, 0x9d, 0xf9,
0xd1, 0x60, 0x97, 0x4d, 0xf3, 0x8f, 0x72, 0xf9, 0xe2, 0x7c, 0x6a, 0xf9, 0x42, 0x85, 0x53, 0xfa, 0xf9, 0x60, 0x24, 0x43, 0xf3, 0x1d, 0xe8, 0x9d, 0x04, 0x36, 0xf5, 0x4e, 0x83, 0xd8, 0x17, 0x69,
0x4e, 0x15, 0xce, 0x3a, 0xde, 0xde, 0x86, 0xc1, 0xa9, 0x17, 0xd8, 0x57, 0x47, 0x7e, 0xce, 0x1b, 0x14, 0xf0, 0x17, 0x38, 0x6d, 0xaa, 0x06, 0xe6, 0xfb, 0xd0, 0xd5, 0x05, 0xd8, 0xbf, 0x08, 0x12,
0x06, 0xd4, 0x99, 0x9f, 0x77, 0x46, 0xd2, 0x35, 0xdf, 0x80, 0xde, 0x49, 0x60, 0x53, 0xef, 0x34, 0xc2, 0xca, 0x4a, 0x75, 0xa9, 0xd8, 0xc6, 0x9b, 0x27, 0xd0, 0xcb, 0xcc, 0x95, 0xdf, 0x77, 0xa0,
0x88, 0x7d, 0x91, 0x7a, 0x01, 0x3f, 0xf5, 0x69, 0x53, 0xd5, 0x31, 0xdf, 0x86, 0xae, 0xce, 0xf4, 0xa6, 0xd4, 0xfa, 0x6c, 0xbd, 0xf4, 0x1d, 0xab, 0x2c, 0x2d, 0xad, 0x5e, 0x73, 0xa8, 0x39, 0x74,
0xfe, 0x45, 0x90, 0x30, 0x63, 0x56, 0x13, 0x94, 0x8a, 0xef, 0x05, 0xf3, 0x04, 0x7a, 0x99, 0xb9, 0xcf, 0xf0, 0x97, 0xd0, 0x23, 0xff, 0x5a, 0x39, 0x3b, 0x06, 0xa2, 0x7e, 0x1b, 0x9d, 0x30, 0xff,
0x9a, 0xf7, 0x0d, 0xa8, 0x29, 0xb5, 0x3e, 0x5b, 0x2f, 0x7d, 0x30, 0x2b, 0x4b, 0x4b, 0xab, 0x37, 0xda, 0xe5, 0x81, 0x8f, 0xad, 0x73, 0x49, 0x37, 0x28, 0x89, 0xe3, 0x74, 0x52, 0x62, 0x61, 0x0d,
0x1c, 0x6a, 0x01, 0xdd, 0x33, 0xfc, 0xe4, 0x7a, 0xe4, 0x5f, 0xab, 0xc9, 0x8e, 0x81, 0xa8, 0x8f, 0xc2, 0x65, 0xd1, 0xda, 0x18, 0x42, 0xf6, 0x3b, 0x8b, 0xac, 0x00, 0x9c, 0xcd, 0x03, 0xc1, 0x26,
0xb0, 0x53, 0xe6, 0x5f, 0xbb, 0x3c, 0xf0, 0xb1, 0x46, 0x2f, 0xe9, 0x4a, 0x28, 0x99, 0x38, 0x1d, 0xd4, 0x71, 0x12, 0x10, 0x83, 0x12, 0x1d, 0x38, 0x0e, 0xdf, 0xff, 0x7b, 0x05, 0xea, 0x1f, 0x2b,
0x94, 0x58, 0x58, 0x83, 0x70, 0x55, 0xb4, 0xd1, 0x87, 0x90, 0x7d, 0xd0, 0x91, 0xa9, 0x86, 0xb3, 0x5e, 0x25, 0xbf, 0x84, 0x4e, 0xa1, 0x18, 0x93, 0x37, 0xb0, 0x69, 0x5b, 0x2e, 0xfd, 0xc3, 0x3b,
0x45, 0x20, 0xd8, 0x94, 0x3a, 0x4e, 0x12, 0x2d, 0xa0, 0x44, 0x07, 0x8e, 0xc3, 0xf7, 0xff, 0x56, 0x2b, 0x62, 0x75, 0xae, 0x0f, 0xa0, 0x9d, 0xaf, 0x91, 0x04, 0xeb, 0x21, 0xfe, 0xea, 0x3b, 0x44,
0x81, 0xfa, 0x47, 0x8a, 0xc0, 0xc9, 0x87, 0xd0, 0x29, 0x64, 0x7d, 0xf2, 0x0a, 0x56, 0x87, 0xab, 0x4f, 0xab, 0x05, 0xf4, 0x1c, 0xb6, 0xd6, 0x55, 0x2f, 0x72, 0x3f, 0x5b, 0x61, 0xb5, 0x72, 0x0e,
0x35, 0xc6, 0xf0, 0xee, 0x9a, 0x58, 0x9d, 0xeb, 0x1d, 0x68, 0xe7, 0x93, 0x31, 0xc1, 0xc4, 0x8b, 0xdf, 0xbc, 0x4d, 0x9b, 0x54, 0xbd, 0xfa, 0xa1, 0xc7, 0xa8, 0x1f, 0x87, 0xf9, 0x1d, 0x64, 0x9f,
0x9f, 0x97, 0x87, 0x38, 0xd3, 0x7a, 0xa6, 0x3e, 0x87, 0xed, 0x4d, 0x69, 0x92, 0x3c, 0xc8, 0x56, 0xe4, 0x31, 0x74, 0x0a, 0xfc, 0xad, 0xce, 0xb9, 0x42, 0xe9, 0xf9, 0x29, 0x8f, 0xa0, 0x8a, 0x35,
0x58, 0x4f, 0xd1, 0xc3, 0x57, 0x6f, 0xd3, 0x26, 0xe9, 0xb5, 0x7e, 0xe8, 0x31, 0xea, 0xc7, 0x61, 0x83, 0x74, 0x0a, 0xc5, 0x6b, 0xd8, 0x4d, 0x87, 0x6a, 0xed, 0xa7, 0x00, 0x59, 0x6f, 0x41, 0x88,
0x7e, 0x07, 0x59, 0x93, 0x3c, 0x81, 0x4e, 0x21, 0x51, 0xa8, 0x73, 0xae, 0xe5, 0x8e, 0xfc, 0x90, 0xf2, 0x9b, 0xef, 0x3e, 0x86, 0x9b, 0x45, 0x59, 0xd2, 0x7f, 0x6c, 0xe0, 0x4f, 0x08, 0xb9, 0xfd,
0xc7, 0x50, 0xc5, 0xe4, 0x44, 0x3a, 0x85, 0x2c, 0x39, 0xec, 0xa6, 0x5d, 0xb5, 0xf6, 0xbb, 0x00, 0xe2, 0x42, 0x69, 0x1d, 0xda, 0xff, 0x4f, 0x09, 0xea, 0xc9, 0xcf, 0xca, 0x8f, 0x61, 0x43, 0x32,
0x59, 0x11, 0x43, 0x88, 0x9a, 0x37, 0x5f, 0xe6, 0x0c, 0xef, 0x14, 0x65, 0x49, 0xa1, 0xb3, 0x85, 0x3a, 0xd9, 0xcc, 0x91, 0x62, 0x52, 0x0d, 0x86, 0x5b, 0x4b, 0x42, 0xb5, 0xc0, 0x08, 0x2a, 0x2f,
0xdf, 0x2a, 0x72, 0xfb, 0xc5, 0x85, 0xd2, 0x84, 0xb7, 0xff, 0x9f, 0x12, 0xd4, 0x93, 0xef, 0xd7, 0x98, 0x50, 0x1b, 0x2a, 0x52, 0xfb, 0x70, 0xb3, 0x28, 0x4b, 0xed, 0xcf, 0xe2, 0xa2, 0xbd, 0x66,
0x4f, 0x60, 0x4b, 0xa6, 0x0e, 0x72, 0x27, 0xc7, 0xbe, 0x49, 0xda, 0x19, 0x6e, 0xaf, 0x08, 0xd5, 0xe6, 0x82, 0x7d, 0xca, 0xb9, 0x1f, 0x42, 0x4d, 0x71, 0xa6, 0x8a, 0xe5, 0x0a, 0xdb, 0x2a, 0xcc,
0x02, 0x63, 0xa8, 0xbc, 0x60, 0x42, 0x6d, 0xa8, 0x98, 0x43, 0x86, 0x77, 0x8a, 0xb2, 0xd4, 0xfe, 0xac, 0xb2, 0xeb, 0xfe, 0x5f, 0x37, 0x00, 0xce, 0x17, 0x91, 0x60, 0xf3, 0xdf, 0xb8, 0xec, 0x15,
0x2c, 0x2e, 0xda, 0xeb, 0x14, 0x50, 0xb0, 0x4f, 0xc9, 0xfd, 0x3d, 0xa8, 0x29, 0x72, 0x56, 0xbe, 0xd9, 0x85, 0x9e, 0xfe, 0xa1, 0x04, 0xdf, 0x6f, 0x92, 0x84, 0x72, 0x31, 0xc1, 0x2e, 0x30, 0xa5,
0x5c, 0xa3, 0x75, 0x85, 0x99, 0x75, 0x1a, 0xdf, 0xff, 0xd7, 0x16, 0xc0, 0xf9, 0x32, 0x12, 0x6c, 0xde, 0x47, 0xd0, 0x3a, 0xa5, 0x37, 0xaf, 0x63, 0x57, 0xd7, 0x84, 0x9c, 0xb7, 0xc1, 0x8a, 0x52,
0xf1, 0x1b, 0x97, 0xbd, 0x24, 0xbb, 0xd0, 0xd3, 0x5f, 0x64, 0xf0, 0xa1, 0x28, 0x49, 0x28, 0xe7, 0x20, 0xea, 0x9f, 0x42, 0x6f, 0x89, 0x8e, 0xf3, 0xf6, 0xf8, 0x1b, 0xc7, 0x5a, 0xba, 0x7e, 0x26,
0x13, 0x2c, 0x37, 0x53, 0x8e, 0x7f, 0x0c, 0xad, 0x53, 0x7a, 0xf3, 0xed, 0x76, 0x1f, 0x42, 0xa7, 0x9f, 0x30, 0x45, 0x4a, 0xce, 0x4f, 0xd4, 0xcf, 0xa9, 0x75, 0x9c, 0xfd, 0xa2, 0xf8, 0xf8, 0xc1,
0x40, 0xdd, 0x7a, 0x8b, 0xab, 0xc9, 0x40, 0x6f, 0x71, 0x9d, 0xe4, 0x1f, 0x43, 0x5d, 0x13, 0x7a, 0x77, 0xa7, 0xb1, 0xcc, 0x9a, 0x09, 0x67, 0x0f, 0xef, 0xae, 0xd3, 0xa4, 0x99, 0x97, 0x27, 0xce,
0x7e, 0x0d, 0x4c, 0x7d, 0x05, 0xa2, 0xff, 0x39, 0xf4, 0x56, 0xe8, 0x3c, 0x6f, 0x8f, 0x1f, 0x63, 0x95, 0xcc, 0x5b, 0x65, 0xd5, 0xf7, 0x00, 0x32, 0xee, 0xcc, 0xdb, 0xe3, 0xf5, 0x2e, 0xd3, 0xea,
0x36, 0xd2, 0xfd, 0x33, 0xf9, 0xd6, 0x2a, 0x52, 0x7a, 0x7e, 0xa0, 0x7e, 0xf7, 0x6d, 0xe2, 0xfc, 0x53, 0x80, 0x8c, 0x11, 0x15, 0x2a, 0x8a, 0x84, 0xaa, 0xa6, 0x2d, 0xb3, 0xe6, 0x2e, 0x34, 0x53,
0x17, 0xc5, 0x57, 0x1a, 0x3e, 0x90, 0x8d, 0x55, 0xd6, 0x4d, 0x38, 0x7f, 0x78, 0x6f, 0x93, 0x26, 0x16, 0xcb, 0xaf, 0x81, 0x0e, 0x8a, 0xa4, 0xf8, 0xf1, 0xee, 0xef, 0x77, 0x66, 0xae, 0xb8, 0x8c,
0x8d, 0xdc, 0x3c, 0xf1, 0xae, 0x45, 0xee, 0x3a, 0x2b, 0xbf, 0x05, 0x90, 0x71, 0x6f, 0xde, 0x1e, 0xa7, 0x23, 0x3b, 0x98, 0xef, 0x5d, 0xd2, 0xe8, 0xd2, 0xb5, 0x03, 0x1e, 0xee, 0x5d, 0x4b, 0x30,
0xe1, 0xb1, 0x4a, 0xcb, 0xef, 0x02, 0x64, 0x8c, 0xaa, 0x50, 0x55, 0x24, 0x64, 0x35, 0x6c, 0x95, 0xec, 0x15, 0xfe, 0xb5, 0x9a, 0xd6, 0xf0, 0xf5, 0xf6, 0xe4, 0x7f, 0x01, 0x00, 0x00, 0xff, 0xff,
0x75, 0x77, 0xa1, 0x99, 0xb2, 0x60, 0x7e, 0x0d, 0x9c, 0xa0, 0x48, 0xaa, 0x1f, 0xed, 0xfe, 0x7e, 0x66, 0x13, 0x8f, 0x1a, 0xcd, 0x1a, 0x00, 0x00,
0x34, 0x77, 0xc5, 0x65, 0x3c, 0x1b, 0xdb, 0xc1, 0x62, 0xef, 0x92, 0x46, 0x97, 0xae, 0x1d, 0xf0,
0x70, 0xef, 0x5a, 0x82, 0x69, 0xaf, 0xf0, 0x7b, 0x6d, 0x56, 0xc3, 0x67, 0xe6, 0xd3, 0xff, 0x05,
0x00, 0x00, 0xff, 0xff, 0xc4, 0xd7, 0xaa, 0x59, 0x76, 0x1b, 0x00, 0x00,
} }
// Reference imports to suppress errors if they are not otherwise used. // Reference imports to suppress errors if they are not otherwise used.
@ -3537,9 +3446,6 @@ type SystemViewClient interface {
// authors should take care not to issue credentials that last longer than // authors should take care not to issue credentials that last longer than
// this value, as Vault will revoke them // this value, as Vault will revoke them
MaxLeaseTTL(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*TTLReply, error) MaxLeaseTTL(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*TTLReply, error)
// SudoPrivilege returns true if given path has sudo privileges
// for the given client token
SudoPrivilege(ctx context.Context, in *SudoPrivilegeArgs, opts ...grpc.CallOption) (*SudoPrivilegeReply, error)
// Tainted, returns true if the mount is tainted. A mount is tainted if it is in the // Tainted, returns true if the mount is tainted. A mount is tainted if it is in the
// process of being unmounted. This should only be used in special // process of being unmounted. This should only be used in special
// circumstances; a primary use-case is as a guard in revocation functions. // circumstances; a primary use-case is as a guard in revocation functions.
@ -3595,15 +3501,6 @@ func (c *systemViewClient) MaxLeaseTTL(ctx context.Context, in *Empty, opts ...g
return out, nil return out, nil
} }
func (c *systemViewClient) SudoPrivilege(ctx context.Context, in *SudoPrivilegeArgs, opts ...grpc.CallOption) (*SudoPrivilegeReply, error) {
out := new(SudoPrivilegeReply)
err := c.cc.Invoke(ctx, "/pb.SystemView/SudoPrivilege", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *systemViewClient) Tainted(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*TaintedReply, error) { func (c *systemViewClient) Tainted(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*TaintedReply, error) {
out := new(TaintedReply) out := new(TaintedReply)
err := c.cc.Invoke(ctx, "/pb.SystemView/Tainted", in, out, opts...) err := c.cc.Invoke(ctx, "/pb.SystemView/Tainted", in, out, opts...)
@ -3684,9 +3581,6 @@ type SystemViewServer interface {
// authors should take care not to issue credentials that last longer than // authors should take care not to issue credentials that last longer than
// this value, as Vault will revoke them // this value, as Vault will revoke them
MaxLeaseTTL(context.Context, *Empty) (*TTLReply, error) MaxLeaseTTL(context.Context, *Empty) (*TTLReply, error)
// SudoPrivilege returns true if given path has sudo privileges
// for the given client token
SudoPrivilege(context.Context, *SudoPrivilegeArgs) (*SudoPrivilegeReply, error)
// Tainted, returns true if the mount is tainted. A mount is tainted if it is in the // Tainted, returns true if the mount is tainted. A mount is tainted if it is in the
// process of being unmounted. This should only be used in special // process of being unmounted. This should only be used in special
// circumstances; a primary use-case is as a guard in revocation functions. // circumstances; a primary use-case is as a guard in revocation functions.
@ -3726,9 +3620,6 @@ func (*UnimplementedSystemViewServer) DefaultLeaseTTL(ctx context.Context, req *
func (*UnimplementedSystemViewServer) MaxLeaseTTL(ctx context.Context, req *Empty) (*TTLReply, error) { func (*UnimplementedSystemViewServer) MaxLeaseTTL(ctx context.Context, req *Empty) (*TTLReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method MaxLeaseTTL not implemented") return nil, status.Errorf(codes.Unimplemented, "method MaxLeaseTTL not implemented")
} }
func (*UnimplementedSystemViewServer) SudoPrivilege(ctx context.Context, req *SudoPrivilegeArgs) (*SudoPrivilegeReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method SudoPrivilege not implemented")
}
func (*UnimplementedSystemViewServer) Tainted(ctx context.Context, req *Empty) (*TaintedReply, error) { func (*UnimplementedSystemViewServer) Tainted(ctx context.Context, req *Empty) (*TaintedReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method Tainted not implemented") return nil, status.Errorf(codes.Unimplemented, "method Tainted not implemented")
} }
@ -3794,24 +3685,6 @@ func _SystemView_MaxLeaseTTL_Handler(srv interface{}, ctx context.Context, dec f
return interceptor(ctx, in, info, handler) return interceptor(ctx, in, info, handler)
} }
func _SystemView_SudoPrivilege_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(SudoPrivilegeArgs)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(SystemViewServer).SudoPrivilege(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/pb.SystemView/SudoPrivilege",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SystemViewServer).SudoPrivilege(ctx, req.(*SudoPrivilegeArgs))
}
return interceptor(ctx, in, info, handler)
}
func _SystemView_Tainted_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { func _SystemView_Tainted_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(Empty) in := new(Empty)
if err := dec(in); err != nil { if err := dec(in); err != nil {
@ -3968,10 +3841,6 @@ var _SystemView_serviceDesc = grpc.ServiceDesc{
MethodName: "MaxLeaseTTL", MethodName: "MaxLeaseTTL",
Handler: _SystemView_MaxLeaseTTL_Handler, Handler: _SystemView_MaxLeaseTTL_Handler,
}, },
{
MethodName: "SudoPrivilege",
Handler: _SystemView_SudoPrivilege_Handler,
},
{ {
MethodName: "Tainted", MethodName: "Tainted",
Handler: _SystemView_Tainted_Handler, Handler: _SystemView_Tainted_Handler,

View file

@ -504,15 +504,6 @@ message TTLReply {
int64 TTL = 1; int64 TTL = 1;
} }
message SudoPrivilegeArgs {
string path = 1;
string token = 2;
}
message SudoPrivilegeReply {
bool sudo = 1;
}
message TaintedReply { message TaintedReply {
bool tainted = 1; bool tainted = 1;
} }
@ -569,10 +560,6 @@ service SystemView {
// this value, as Vault will revoke them // this value, as Vault will revoke them
rpc MaxLeaseTTL(Empty) returns (TTLReply); rpc MaxLeaseTTL(Empty) returns (TTLReply);
// SudoPrivilege returns true if given path has sudo privileges
// for the given client token
rpc SudoPrivilege(SudoPrivilegeArgs) returns (SudoPrivilegeReply);
// Tainted, returns true if the mount is tainted. A mount is tainted if it is in the // Tainted, returns true if the mount is tainted. A mount is tainted if it is in the
// process of being unmounted. This should only be used in special // process of being unmounted. This should only be used in special
// circumstances; a primary use-case is as a guard in revocation functions. // circumstances; a primary use-case is as a guard in revocation functions.

View file

@ -27,11 +27,19 @@ type dynamicSystemView struct {
mountEntry *MountEntry mountEntry *MountEntry
} }
type extendedSystemView struct { type extendedSystemView interface {
logical.SystemView
logical.ExtendedSystemView
// SudoPrivilege won't work over the plugin system so we keep it here
// instead of in sdk/logical to avoid exposing to plugins
SudoPrivilege(context.Context, string, string) bool
}
type extendedSystemViewImpl struct {
dynamicSystemView dynamicSystemView
} }
func (e extendedSystemView) Auditor() logical.Auditor { func (e extendedSystemViewImpl) Auditor() logical.Auditor {
return genericAuditor{ return genericAuditor{
mountType: e.mountEntry.Type, mountType: e.mountEntry.Type,
namespace: e.mountEntry.Namespace(), namespace: e.mountEntry.Namespace(),
@ -39,7 +47,7 @@ func (e extendedSystemView) Auditor() logical.Auditor {
} }
} }
func (e extendedSystemView) ForwardGenericRequest(ctx context.Context, req *logical.Request) (*logical.Response, error) { func (e extendedSystemViewImpl) ForwardGenericRequest(ctx context.Context, req *logical.Request) (*logical.Response, error) {
// Forward the request if allowed // Forward the request if allowed
if couldForward(e.core) { if couldForward(e.core) {
ctx = namespace.ContextWithNamespace(ctx, e.mountEntry.Namespace()) ctx = namespace.ContextWithNamespace(ctx, e.mountEntry.Namespace())
@ -50,27 +58,19 @@ func (e extendedSystemView) ForwardGenericRequest(ctx context.Context, req *logi
return nil, logical.ErrReadOnly return nil, logical.ErrReadOnly
} }
func (d dynamicSystemView) DefaultLeaseTTL() time.Duration { // SudoPrivilege returns true if given path has sudo privileges
def, _ := d.fetchTTLs() // for the given client token
return def func (e extendedSystemViewImpl) SudoPrivilege(ctx context.Context, path string, token string) bool {
}
func (d dynamicSystemView) MaxLeaseTTL() time.Duration {
_, max := d.fetchTTLs()
return max
}
func (d dynamicSystemView) SudoPrivilege(ctx context.Context, path string, token string) bool {
// Resolve the token policy // Resolve the token policy
te, err := d.core.tokenStore.Lookup(ctx, token) te, err := e.core.tokenStore.Lookup(ctx, token)
if err != nil { if err != nil {
d.core.logger.Error("failed to lookup token", "error", err) e.core.logger.Error("failed to lookup token", "error", err)
return false return false
} }
// Ensure the token is valid // Ensure the token is valid
if te == nil { if te == nil {
d.core.logger.Error("entry not found for given token") e.core.logger.Error("entry not found for given token")
return false return false
} }
@ -78,20 +78,20 @@ func (d dynamicSystemView) SudoPrivilege(ctx context.Context, path string, token
// Add token policies // Add token policies
policies[te.NamespaceID] = append(policies[te.NamespaceID], te.Policies...) policies[te.NamespaceID] = append(policies[te.NamespaceID], te.Policies...)
tokenNS, err := NamespaceByID(ctx, te.NamespaceID, d.core) tokenNS, err := NamespaceByID(ctx, te.NamespaceID, e.core)
if err != nil { if err != nil {
d.core.logger.Error("failed to lookup token namespace", "error", err) e.core.logger.Error("failed to lookup token namespace", "error", err)
return false return false
} }
if tokenNS == nil { if tokenNS == nil {
d.core.logger.Error("failed to lookup token namespace", "error", namespace.ErrNoNamespace) e.core.logger.Error("failed to lookup token namespace", "error", namespace.ErrNoNamespace)
return false return false
} }
// Add identity policies from all the namespaces // Add identity policies from all the namespaces
entity, identityPolicies, err := d.core.fetchEntityAndDerivedPolicies(ctx, tokenNS, te.EntityID) entity, identityPolicies, err := e.core.fetchEntityAndDerivedPolicies(ctx, tokenNS, te.EntityID)
if err != nil { if err != nil {
d.core.logger.Error("failed to fetch identity policies", "error", err) e.core.logger.Error("failed to fetch identity policies", "error", err)
return false return false
} }
for nsID, nsPolicies := range identityPolicies { for nsID, nsPolicies := range identityPolicies {
@ -102,9 +102,9 @@ func (d dynamicSystemView) SudoPrivilege(ctx context.Context, path string, token
// Construct the corresponding ACL object. Derive and use a new context that // Construct the corresponding ACL object. Derive and use a new context that
// uses the req.ClientToken's namespace // uses the req.ClientToken's namespace
acl, err := d.core.policyStore.ACL(tokenCtx, entity, policies) acl, err := e.core.policyStore.ACL(tokenCtx, entity, policies)
if err != nil { if err != nil {
d.core.logger.Error("failed to retrieve ACL for token's policies", "token_policies", te.Policies, "error", err) e.core.logger.Error("failed to retrieve ACL for token's policies", "token_policies", te.Policies, "error", err)
return false return false
} }
@ -120,6 +120,16 @@ func (d dynamicSystemView) SudoPrivilege(ctx context.Context, path string, token
return authResults.RootPrivs return authResults.RootPrivs
} }
func (d dynamicSystemView) DefaultLeaseTTL() time.Duration {
def, _ := d.fetchTTLs()
return def
}
func (d dynamicSystemView) MaxLeaseTTL() time.Duration {
_, max := d.fetchTTLs()
return max
}
// TTLsByPath returns the default and max TTLs corresponding to a particular // TTLsByPath returns the default and max TTLs corresponding to a particular
// mount point, or the system default // mount point, or the system default
func (d dynamicSystemView) fetchTTLs() (def, max time.Duration) { func (d dynamicSystemView) fetchTTLs() (def, max time.Duration) {

View file

@ -1252,8 +1252,8 @@ func (c *Core) newLogicalBackend(ctx context.Context, entry *MountEntry, sysView
// mountEntrySysView creates a logical.SystemView from global and // mountEntrySysView creates a logical.SystemView from global and
// mount-specific entries; because this should be called when setting // mount-specific entries; because this should be called when setting
// up a mountEntry, it doesn't check to ensure that me is not nil // up a mountEntry, it doesn't check to ensure that me is not nil
func (c *Core) mountEntrySysView(entry *MountEntry) logical.SystemView { func (c *Core) mountEntrySysView(entry *MountEntry) extendedSystemView {
return extendedSystemView{ return extendedSystemViewImpl{
dynamicSystemView{ dynamicSystemView{
core: c, core: c,
mountEntry: entry, mountEntry: entry,

View file

@ -2095,7 +2095,7 @@ func (ts *TokenStore) handleCreateCommon(ctx context.Context, req *logical.Reque
} }
// Check if the client token has sudo/root privileges for the requested path // Check if the client token has sudo/root privileges for the requested path
isSudo := ts.System().SudoPrivilege(ctx, req.MountPoint+req.Path, req.ClientToken) isSudo := ts.System().(extendedSystemView).SudoPrivilege(ctx, req.MountPoint+req.Path, req.ClientToken)
// Read and parse the fields // Read and parse the fields
var data struct { var data struct {
@ -2589,7 +2589,7 @@ func (ts *TokenStore) handleCreateCommon(ctx context.Context, req *logical.Reque
} }
} }
sysView := ts.System() sysView := ts.System().(extendedSystemView)
// Only calculate a TTL if you are A) periodic, B) have a TTL, C) do not have a TTL and are not a root token // Only calculate a TTL if you are A) periodic, B) have a TTL, C) do not have a TTL and are not a root token
if periodToUse > 0 || te.TTL > 0 || (te.TTL == 0 && !strutil.StrListContains(te.Policies, "root")) { if periodToUse > 0 || te.TTL > 0 || (te.TTL == 0 && !strutil.StrListContains(te.Policies, "root")) {
@ -2729,7 +2729,7 @@ func (ts *TokenStore) handleRevokeOrphan(ctx context.Context, req *logical.Reque
} }
// Check if the client token has sudo/root privileges for the requested path // Check if the client token has sudo/root privileges for the requested path
isSudo := ts.System().SudoPrivilege(ctx, req.MountPoint+req.Path, req.ClientToken) isSudo := ts.System().(extendedSystemView).SudoPrivilege(ctx, req.MountPoint+req.Path, req.ClientToken)
if !isSudo { if !isSudo {
return logical.ErrorResponse("root or sudo privileges required to revoke and orphan"), return logical.ErrorResponse("root or sudo privileges required to revoke and orphan"),