forked from TrueCloudLab/frostfs-node
[#589] ir/container: Verify session token lifetime
Session tokens have limited lifetime in NeoFS. Container processor should verify lifetime of the incoming tokens. Define `NetworkState` interface with `Epoch` method to get number of the current epoch. Use Netmap contract client's wrapper as `NetworkState` of Container `Processor`. Check values of token lifetime, and deny if: * NBF value is gt the current epoch; * IAT is gt the current epoch; * EXP is le the current epoch. Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
This commit is contained in:
parent
0bfa2dc88f
commit
2f38fef31a
5 changed files with 47 additions and 1 deletions
2
go.mod
2
go.mod
|
@ -13,7 +13,7 @@ require (
|
||||||
github.com/multiformats/go-multiaddr v0.3.1
|
github.com/multiformats/go-multiaddr v0.3.1
|
||||||
github.com/nspcc-dev/hrw v1.0.9
|
github.com/nspcc-dev/hrw v1.0.9
|
||||||
github.com/nspcc-dev/neo-go v0.95.1
|
github.com/nspcc-dev/neo-go v0.95.1
|
||||||
github.com/nspcc-dev/neofs-api-go v1.27.0
|
github.com/nspcc-dev/neofs-api-go v1.27.1-0.20210607102659-cc1163fd5797
|
||||||
github.com/nspcc-dev/neofs-crypto v0.3.0
|
github.com/nspcc-dev/neofs-crypto v0.3.0
|
||||||
github.com/nspcc-dev/neofs-sdk-go v0.0.0-20210520210714-9dee13f0d556
|
github.com/nspcc-dev/neofs-sdk-go v0.0.0-20210520210714-9dee13f0d556
|
||||||
github.com/nspcc-dev/tzhash v1.4.0
|
github.com/nspcc-dev/tzhash v1.4.0
|
||||||
|
|
BIN
go.sum
BIN
go.sum
Binary file not shown.
|
@ -561,6 +561,7 @@ func New(ctx context.Context, log *zap.Logger, cfg *viper.Viper) (*Server, error
|
||||||
FeeProvider: server.feeConfig,
|
FeeProvider: server.feeConfig,
|
||||||
ContainerClient: cnrClient,
|
ContainerClient: cnrClient,
|
||||||
NeoFSIDClient: neofsIDClient,
|
NeoFSIDClient: neofsIDClient,
|
||||||
|
NetworkState: nmClient,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -106,6 +106,12 @@ func (cp *Processor) checkSessionToken(token *session.Token) error {
|
||||||
return errors.New("invalid signature")
|
return errors.New("invalid signature")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check lifetime
|
||||||
|
err := cp.checkTokenLifetime(token)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// check token owner's key ownership
|
// check token owner's key ownership
|
||||||
|
|
||||||
key, err := keys.NewPublicKeyFromBytes(token.Signature().Key(), elliptic.P256())
|
key, err := keys.NewPublicKeyFromBytes(token.Signature().Key(), elliptic.P256())
|
||||||
|
@ -149,3 +155,27 @@ func checkTokenContextWithCID(tok *session.Token, id *cid.ID, verbAssert verbAss
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cp *Processor) checkTokenLifetime(token *session.Token) error {
|
||||||
|
curEpoch, err := cp.netState.Epoch()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("could not read current epoch: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
nbf := token.Nbf()
|
||||||
|
if curEpoch < nbf {
|
||||||
|
return fmt.Errorf("token is not valid yet: nbf %d, cur %d", nbf, curEpoch)
|
||||||
|
}
|
||||||
|
|
||||||
|
iat := token.Iat()
|
||||||
|
if curEpoch < iat {
|
||||||
|
return fmt.Errorf("token is issued in future: iat %d, cur %d", iat, curEpoch)
|
||||||
|
}
|
||||||
|
|
||||||
|
exp := token.Exp()
|
||||||
|
if curEpoch >= exp {
|
||||||
|
return fmt.Errorf("token is expired: exp %d, cur %d", exp, curEpoch)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@ type (
|
||||||
feeProvider *config.FeeConfig
|
feeProvider *config.FeeConfig
|
||||||
cnrClient *wrapper.Wrapper // notary must be enabled
|
cnrClient *wrapper.Wrapper // notary must be enabled
|
||||||
idClient *neofsid.ClientWrapper
|
idClient *neofsid.ClientWrapper
|
||||||
|
netState NetworkState
|
||||||
}
|
}
|
||||||
|
|
||||||
// Params of the processor constructor.
|
// Params of the processor constructor.
|
||||||
|
@ -43,9 +44,20 @@ type (
|
||||||
FeeProvider *config.FeeConfig
|
FeeProvider *config.FeeConfig
|
||||||
ContainerClient *wrapper.Wrapper
|
ContainerClient *wrapper.Wrapper
|
||||||
NeoFSIDClient *neofsid.ClientWrapper
|
NeoFSIDClient *neofsid.ClientWrapper
|
||||||
|
NetworkState NetworkState
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// NetworkState is an interface of a component
|
||||||
|
// that provides access to network state.
|
||||||
|
type NetworkState interface {
|
||||||
|
// Epoch must return number of the current epoch.
|
||||||
|
//
|
||||||
|
// Must return any error encountered
|
||||||
|
// which did not allow reading the value.
|
||||||
|
Epoch() (uint64, error)
|
||||||
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
putNotification = "containerPut"
|
putNotification = "containerPut"
|
||||||
deleteNotification = "containerDelete"
|
deleteNotification = "containerDelete"
|
||||||
|
@ -68,6 +80,8 @@ func New(p *Params) (*Processor, error) {
|
||||||
return nil, errors.New("ir/container: Container client is not set")
|
return nil, errors.New("ir/container: Container client is not set")
|
||||||
case p.NeoFSIDClient == nil:
|
case p.NeoFSIDClient == nil:
|
||||||
return nil, errors.New("ir/container: NeoFS ID client is not set")
|
return nil, errors.New("ir/container: NeoFS ID client is not set")
|
||||||
|
case p.NetworkState == nil:
|
||||||
|
return nil, errors.New("ir/container: network state is not set")
|
||||||
}
|
}
|
||||||
|
|
||||||
p.Log.Debug("container worker pool", zap.Int("size", p.PoolSize))
|
p.Log.Debug("container worker pool", zap.Int("size", p.PoolSize))
|
||||||
|
@ -86,6 +100,7 @@ func New(p *Params) (*Processor, error) {
|
||||||
feeProvider: p.FeeProvider,
|
feeProvider: p.FeeProvider,
|
||||||
cnrClient: p.ContainerClient,
|
cnrClient: p.ContainerClient,
|
||||||
idClient: p.NeoFSIDClient,
|
idClient: p.NeoFSIDClient,
|
||||||
|
netState: p.NetworkState,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue