1package plugin 2 3import ( 4 "context" 5 "encoding/json" 6 "errors" 7 "fmt" 8 "time" 9 10 "github.com/hashicorp/vault/sdk/helper/consts" 11 "github.com/hashicorp/vault/sdk/helper/license" 12 "github.com/hashicorp/vault/sdk/helper/pluginutil" 13 "github.com/hashicorp/vault/sdk/helper/wrapping" 14 "github.com/hashicorp/vault/sdk/logical" 15 "github.com/hashicorp/vault/sdk/plugin/pb" 16 "google.golang.org/grpc" 17) 18 19func newGRPCSystemView(conn *grpc.ClientConn) *gRPCSystemViewClient { 20 return &gRPCSystemViewClient{ 21 client: pb.NewSystemViewClient(conn), 22 } 23} 24 25type gRPCSystemViewClient struct { 26 client pb.SystemViewClient 27} 28 29func (s *gRPCSystemViewClient) DefaultLeaseTTL() time.Duration { 30 reply, err := s.client.DefaultLeaseTTL(context.Background(), &pb.Empty{}) 31 if err != nil { 32 return 0 33 } 34 35 return time.Duration(reply.TTL) 36} 37 38func (s *gRPCSystemViewClient) MaxLeaseTTL() time.Duration { 39 reply, err := s.client.MaxLeaseTTL(context.Background(), &pb.Empty{}) 40 if err != nil { 41 return 0 42 } 43 44 return time.Duration(reply.TTL) 45} 46 47func (s *gRPCSystemViewClient) SudoPrivilege(ctx context.Context, path string, token string) bool { 48 reply, err := s.client.SudoPrivilege(ctx, &pb.SudoPrivilegeArgs{ 49 Path: path, 50 Token: token, 51 }) 52 if err != nil { 53 return false 54 } 55 56 return reply.Sudo 57} 58 59func (s *gRPCSystemViewClient) Tainted() bool { 60 reply, err := s.client.Tainted(context.Background(), &pb.Empty{}) 61 if err != nil { 62 return false 63 } 64 65 return reply.Tainted 66} 67 68func (s *gRPCSystemViewClient) CachingDisabled() bool { 69 reply, err := s.client.CachingDisabled(context.Background(), &pb.Empty{}) 70 if err != nil { 71 return false 72 } 73 74 return reply.Disabled 75} 76 77func (s *gRPCSystemViewClient) ReplicationState() consts.ReplicationState { 78 reply, err := s.client.ReplicationState(context.Background(), &pb.Empty{}) 79 if err != nil { 80 return consts.ReplicationUnknown 81 } 82 83 return consts.ReplicationState(reply.State) 84} 85 86func (s *gRPCSystemViewClient) ResponseWrapData(ctx context.Context, data map[string]interface{}, ttl time.Duration, jwt bool) (*wrapping.ResponseWrapInfo, error) { 87 buf, err := json.Marshal(data) 88 if err != nil { 89 return nil, err 90 } 91 92 reply, err := s.client.ResponseWrapData(ctx, &pb.ResponseWrapDataArgs{ 93 Data: string(buf[:]), 94 TTL: int64(ttl), 95 JWT: false, 96 }) 97 if err != nil { 98 return nil, err 99 } 100 if reply.Err != "" { 101 return nil, errors.New(reply.Err) 102 } 103 104 info, err := pb.ProtoResponseWrapInfoToLogicalResponseWrapInfo(reply.WrapInfo) 105 if err != nil { 106 return nil, err 107 } 108 109 return info, nil 110} 111 112func (s *gRPCSystemViewClient) LookupPlugin(_ context.Context, _ string, _ consts.PluginType) (*pluginutil.PluginRunner, error) { 113 return nil, fmt.Errorf("cannot call LookupPlugin from a plugin backend") 114} 115 116func (s *gRPCSystemViewClient) MlockEnabled() bool { 117 reply, err := s.client.MlockEnabled(context.Background(), &pb.Empty{}) 118 if err != nil { 119 return false 120 } 121 122 return reply.Enabled 123} 124 125func (s *gRPCSystemViewClient) HasFeature(feature license.Features) bool { 126 // Not implemented 127 return false 128} 129 130func (s *gRPCSystemViewClient) LocalMount() bool { 131 reply, err := s.client.LocalMount(context.Background(), &pb.Empty{}) 132 if err != nil { 133 return false 134 } 135 136 return reply.Local 137} 138 139func (s *gRPCSystemViewClient) EntityInfo(entityID string) (*logical.Entity, error) { 140 reply, err := s.client.EntityInfo(context.Background(), &pb.EntityInfoArgs{ 141 EntityID: entityID, 142 }) 143 if err != nil { 144 return nil, err 145 } 146 if reply.Err != "" { 147 return nil, errors.New(reply.Err) 148 } 149 150 return reply.Entity, nil 151} 152 153func (s *gRPCSystemViewClient) PluginEnv(ctx context.Context) (*logical.PluginEnvironment, error) { 154 reply, err := s.client.PluginEnv(ctx, &pb.Empty{}) 155 if err != nil { 156 return nil, err 157 } 158 159 return reply.PluginEnvironment, nil 160} 161 162type gRPCSystemViewServer struct { 163 impl logical.SystemView 164} 165 166func (s *gRPCSystemViewServer) DefaultLeaseTTL(ctx context.Context, _ *pb.Empty) (*pb.TTLReply, error) { 167 ttl := s.impl.DefaultLeaseTTL() 168 return &pb.TTLReply{ 169 TTL: int64(ttl), 170 }, nil 171} 172 173func (s *gRPCSystemViewServer) MaxLeaseTTL(ctx context.Context, _ *pb.Empty) (*pb.TTLReply, error) { 174 ttl := s.impl.MaxLeaseTTL() 175 return &pb.TTLReply{ 176 TTL: int64(ttl), 177 }, nil 178} 179 180func (s *gRPCSystemViewServer) SudoPrivilege(ctx context.Context, args *pb.SudoPrivilegeArgs) (*pb.SudoPrivilegeReply, error) { 181 sudo := s.impl.SudoPrivilege(ctx, args.Path, args.Token) 182 return &pb.SudoPrivilegeReply{ 183 Sudo: sudo, 184 }, nil 185} 186 187func (s *gRPCSystemViewServer) Tainted(ctx context.Context, _ *pb.Empty) (*pb.TaintedReply, error) { 188 tainted := s.impl.Tainted() 189 return &pb.TaintedReply{ 190 Tainted: tainted, 191 }, nil 192} 193 194func (s *gRPCSystemViewServer) CachingDisabled(ctx context.Context, _ *pb.Empty) (*pb.CachingDisabledReply, error) { 195 cachingDisabled := s.impl.CachingDisabled() 196 return &pb.CachingDisabledReply{ 197 Disabled: cachingDisabled, 198 }, nil 199} 200 201func (s *gRPCSystemViewServer) ReplicationState(ctx context.Context, _ *pb.Empty) (*pb.ReplicationStateReply, error) { 202 replicationState := s.impl.ReplicationState() 203 return &pb.ReplicationStateReply{ 204 State: int32(replicationState), 205 }, nil 206} 207 208func (s *gRPCSystemViewServer) ResponseWrapData(ctx context.Context, args *pb.ResponseWrapDataArgs) (*pb.ResponseWrapDataReply, error) { 209 data := map[string]interface{}{} 210 err := json.Unmarshal([]byte(args.Data), &data) 211 if err != nil { 212 return &pb.ResponseWrapDataReply{}, err 213 } 214 215 // Do not allow JWTs to be returned 216 info, err := s.impl.ResponseWrapData(ctx, data, time.Duration(args.TTL), false) 217 if err != nil { 218 return &pb.ResponseWrapDataReply{ 219 Err: pb.ErrToString(err), 220 }, nil 221 } 222 223 pbInfo, err := pb.LogicalResponseWrapInfoToProtoResponseWrapInfo(info) 224 if err != nil { 225 return &pb.ResponseWrapDataReply{}, err 226 } 227 228 return &pb.ResponseWrapDataReply{ 229 WrapInfo: pbInfo, 230 }, nil 231} 232 233func (s *gRPCSystemViewServer) MlockEnabled(ctx context.Context, _ *pb.Empty) (*pb.MlockEnabledReply, error) { 234 enabled := s.impl.MlockEnabled() 235 return &pb.MlockEnabledReply{ 236 Enabled: enabled, 237 }, nil 238} 239 240func (s *gRPCSystemViewServer) LocalMount(ctx context.Context, _ *pb.Empty) (*pb.LocalMountReply, error) { 241 local := s.impl.LocalMount() 242 return &pb.LocalMountReply{ 243 Local: local, 244 }, nil 245} 246 247func (s *gRPCSystemViewServer) EntityInfo(ctx context.Context, args *pb.EntityInfoArgs) (*pb.EntityInfoReply, error) { 248 entity, err := s.impl.EntityInfo(args.EntityID) 249 if err != nil { 250 return &pb.EntityInfoReply{ 251 Err: pb.ErrToString(err), 252 }, nil 253 } 254 return &pb.EntityInfoReply{ 255 Entity: entity, 256 }, nil 257} 258 259func (s *gRPCSystemViewServer) PluginEnv(ctx context.Context, _ *pb.Empty) (*pb.PluginEnvReply, error) { 260 pluginEnv, err := s.impl.PluginEnv(ctx) 261 if err != nil { 262 return &pb.PluginEnvReply{ 263 Err: pb.ErrToString(err), 264 }, nil 265 } 266 return &pb.PluginEnvReply{ 267 PluginEnvironment: pluginEnv, 268 }, nil 269} 270