Skip to content

Commit 3de0209

Browse files
Merge pull request #3 from ava-labs/master
updating against ava-labs base
2 parents e771c2f + b1923d7 commit 3de0209

File tree

111 files changed

+4198
-1803
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

111 files changed

+4198
-1803
lines changed

api/admin/service.go

Lines changed: 40 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,19 @@ import (
1010

1111
"github.com/ava-labs/gecko/api"
1212
"github.com/ava-labs/gecko/chains"
13+
"github.com/ava-labs/gecko/genesis"
1314
"github.com/ava-labs/gecko/ids"
1415
"github.com/ava-labs/gecko/network"
1516
"github.com/ava-labs/gecko/snow/engine/common"
1617
"github.com/ava-labs/gecko/utils/logging"
18+
"github.com/ava-labs/gecko/version"
1719

1820
cjson "github.com/ava-labs/gecko/utils/json"
1921
)
2022

2123
// Admin is the API service for node admin management
2224
type Admin struct {
25+
version version.Version
2326
nodeID ids.ShortID
2427
networkID uint32
2528
log logging.Logger
@@ -30,12 +33,13 @@ type Admin struct {
3033
}
3134

3235
// NewService returns a new admin API service
33-
func NewService(nodeID ids.ShortID, networkID uint32, log logging.Logger, chainManager chains.Manager, peers network.Network, httpServer *api.Server) *common.HTTPHandler {
36+
func NewService(version version.Version, nodeID ids.ShortID, networkID uint32, log logging.Logger, chainManager chains.Manager, peers network.Network, httpServer *api.Server) *common.HTTPHandler {
3437
newServer := rpc.NewServer()
3538
codec := cjson.NewCodec()
3639
newServer.RegisterCodec(codec, "application/json")
3740
newServer.RegisterCodec(codec, "application/json;charset=UTF-8")
3841
newServer.RegisterService(&Admin{
42+
version: version,
3943
nodeID: nodeID,
4044
networkID: networkID,
4145
log: log,
@@ -46,38 +50,58 @@ func NewService(nodeID ids.ShortID, networkID uint32, log logging.Logger, chainM
4650
return &common.HTTPHandler{Handler: newServer}
4751
}
4852

49-
// GetNodeIDArgs are the arguments for calling GetNodeID
50-
type GetNodeIDArgs struct{}
53+
// GetNodeVersionReply are the results from calling GetNodeVersion
54+
type GetNodeVersionReply struct {
55+
Version string `json:"version"`
56+
}
57+
58+
// GetNodeVersion returns the version this node is running
59+
func (service *Admin) GetNodeVersion(_ *http.Request, _ *struct{}, reply *GetNodeVersionReply) error {
60+
service.log.Debug("Admin: GetNodeVersion called")
61+
62+
reply.Version = service.version.String()
63+
return nil
64+
}
5165

5266
// GetNodeIDReply are the results from calling GetNodeID
5367
type GetNodeIDReply struct {
5468
NodeID ids.ShortID `json:"nodeID"`
5569
}
5670

5771
// GetNodeID returns the node ID of this node
58-
func (service *Admin) GetNodeID(r *http.Request, args *GetNodeIDArgs, reply *GetNodeIDReply) error {
72+
func (service *Admin) GetNodeID(_ *http.Request, _ *struct{}, reply *GetNodeIDReply) error {
5973
service.log.Debug("Admin: GetNodeID called")
6074

6175
reply.NodeID = service.nodeID
6276
return nil
6377
}
6478

65-
// GetNetworkIDArgs are the arguments for calling GetNetworkID
66-
type GetNetworkIDArgs struct{}
67-
6879
// GetNetworkIDReply are the results from calling GetNetworkID
6980
type GetNetworkIDReply struct {
7081
NetworkID cjson.Uint32 `json:"networkID"`
7182
}
7283

7384
// GetNetworkID returns the network ID this node is running on
74-
func (service *Admin) GetNetworkID(r *http.Request, args *GetNetworkIDArgs, reply *GetNetworkIDReply) error {
85+
func (service *Admin) GetNetworkID(_ *http.Request, _ *struct{}, reply *GetNetworkIDReply) error {
7586
service.log.Debug("Admin: GetNetworkID called")
7687

7788
reply.NetworkID = cjson.Uint32(service.networkID)
7889
return nil
7990
}
8091

92+
// GetNetworkNameReply is the result from calling GetNetworkName
93+
type GetNetworkNameReply struct {
94+
NetworkName string `json:"networkName"`
95+
}
96+
97+
// GetNetworkName returns the network name this node is running on
98+
func (service *Admin) GetNetworkName(_ *http.Request, _ *struct{}, reply *GetNetworkNameReply) error {
99+
service.log.Debug("Admin: GetNetworkName called")
100+
101+
reply.NetworkName = genesis.NetworkName(service.networkID)
102+
return nil
103+
}
104+
81105
// GetBlockchainIDArgs are the arguments for calling GetBlockchainID
82106
type GetBlockchainIDArgs struct {
83107
Alias string `json:"alias"`
@@ -89,24 +113,21 @@ type GetBlockchainIDReply struct {
89113
}
90114

91115
// GetBlockchainID returns the blockchain ID that resolves the alias that was supplied
92-
func (service *Admin) GetBlockchainID(r *http.Request, args *GetBlockchainIDArgs, reply *GetBlockchainIDReply) error {
116+
func (service *Admin) GetBlockchainID(_ *http.Request, args *GetBlockchainIDArgs, reply *GetBlockchainIDReply) error {
93117
service.log.Debug("Admin: GetBlockchainID called")
94118

95119
bID, err := service.chainManager.Lookup(args.Alias)
96120
reply.BlockchainID = bID.String()
97121
return err
98122
}
99123

100-
// PeersArgs are the arguments for calling Peers
101-
type PeersArgs struct{}
102-
103124
// PeersReply are the results from calling Peers
104125
type PeersReply struct {
105126
Peers []network.PeerID `json:"peers"`
106127
}
107128

108129
// Peers returns the list of current validators
109-
func (service *Admin) Peers(r *http.Request, args *PeersArgs, reply *PeersReply) error {
130+
func (service *Admin) Peers(_ *http.Request, _ *struct{}, reply *PeersReply) error {
110131
service.log.Debug("Admin: Peers called")
111132
reply.Peers = service.networking.Peers()
112133
return nil
@@ -123,22 +144,19 @@ type StartCPUProfilerReply struct {
123144
}
124145

125146
// StartCPUProfiler starts a cpu profile writing to the specified file
126-
func (service *Admin) StartCPUProfiler(r *http.Request, args *StartCPUProfilerArgs, reply *StartCPUProfilerReply) error {
147+
func (service *Admin) StartCPUProfiler(_ *http.Request, args *StartCPUProfilerArgs, reply *StartCPUProfilerReply) error {
127148
service.log.Debug("Admin: StartCPUProfiler called with %s", args.Filename)
128149
reply.Success = true
129150
return service.performance.StartCPUProfiler(args.Filename)
130151
}
131152

132-
// StopCPUProfilerArgs are the arguments for calling StopCPUProfiler
133-
type StopCPUProfilerArgs struct{}
134-
135153
// StopCPUProfilerReply are the results from calling StopCPUProfiler
136154
type StopCPUProfilerReply struct {
137155
Success bool `json:"success"`
138156
}
139157

140158
// StopCPUProfiler stops the cpu profile
141-
func (service *Admin) StopCPUProfiler(r *http.Request, args *StopCPUProfilerArgs, reply *StopCPUProfilerReply) error {
159+
func (service *Admin) StopCPUProfiler(_ *http.Request, _ *struct{}, reply *StopCPUProfilerReply) error {
142160
service.log.Debug("Admin: StopCPUProfiler called")
143161
reply.Success = true
144162
return service.performance.StopCPUProfiler()
@@ -155,7 +173,7 @@ type MemoryProfileReply struct {
155173
}
156174

157175
// MemoryProfile runs a memory profile writing to the specified file
158-
func (service *Admin) MemoryProfile(r *http.Request, args *MemoryProfileArgs, reply *MemoryProfileReply) error {
176+
func (service *Admin) MemoryProfile(_ *http.Request, args *MemoryProfileArgs, reply *MemoryProfileReply) error {
159177
service.log.Debug("Admin: MemoryProfile called with %s", args.Filename)
160178
reply.Success = true
161179
return service.performance.MemoryProfile(args.Filename)
@@ -172,7 +190,7 @@ type LockProfileReply struct {
172190
}
173191

174192
// LockProfile runs a mutex profile writing to the specified file
175-
func (service *Admin) LockProfile(r *http.Request, args *LockProfileArgs, reply *LockProfileReply) error {
193+
func (service *Admin) LockProfile(_ *http.Request, args *LockProfileArgs, reply *LockProfileReply) error {
176194
service.log.Debug("Admin: LockProfile called with %s", args.Filename)
177195
reply.Success = true
178196
return service.performance.LockProfile(args.Filename)
@@ -190,7 +208,7 @@ type AliasReply struct {
190208
}
191209

192210
// Alias attempts to alias an HTTP endpoint to a new name
193-
func (service *Admin) Alias(r *http.Request, args *AliasArgs, reply *AliasReply) error {
211+
func (service *Admin) Alias(_ *http.Request, args *AliasArgs, reply *AliasReply) error {
194212
service.log.Debug("Admin: Alias called with URL: %s, Alias: %s", args.Endpoint, args.Alias)
195213
reply.Success = true
196214
return service.httpServer.AddAliasesWithReadLock(args.Endpoint, args.Alias)
@@ -233,7 +251,7 @@ type StacktraceReply struct {
233251
}
234252

235253
// Stacktrace returns the current global stacktrace
236-
func (service *Admin) Stacktrace(_ *http.Request, _ *StacktraceArgs, reply *StacktraceReply) error {
254+
func (service *Admin) Stacktrace(_ *http.Request, _ *struct{}, reply *StacktraceReply) error {
237255
reply.Stacktrace = logging.Stacktrace{Global: true}.String()
238256
return nil
239257
}

api/keystore/service.go

Lines changed: 66 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,14 @@ import (
88
"fmt"
99
"net/http"
1010
"sync"
11+
"testing"
1112

1213
"github.com/gorilla/rpc/v2"
1314

1415
"github.com/ava-labs/gecko/chains/atomic"
1516
"github.com/ava-labs/gecko/database"
1617
"github.com/ava-labs/gecko/database/encdb"
18+
"github.com/ava-labs/gecko/database/memdb"
1719
"github.com/ava-labs/gecko/database/prefixdb"
1820
"github.com/ava-labs/gecko/ids"
1921
"github.com/ava-labs/gecko/snow/engine/common"
@@ -29,8 +31,17 @@ const (
2931
// maxUserPassLen is the maximum length of the username or password allowed
3032
maxUserPassLen = 1024
3133

32-
// requiredPassScore defines the score a password must achieve to be accepted
33-
// as a password with strong characteristics by the zxcvbn package
34+
// maxCheckedPassLen limits the length of the password that should be
35+
// strength checked.
36+
//
37+
// As per issue https://github.com/ava-labs/gecko/issues/195 it was found
38+
// the longer the length of password the slower zxcvbn.PasswordStrength()
39+
// performs. To avoid performance issues, and a DoS vector, we only check
40+
// the first 50 characters of the password.
41+
maxCheckedPassLen = 50
42+
43+
// requiredPassScore defines the score a password must achieve to be
44+
// accepted as a password with strong characteristics by the zxcvbn package
3445
//
3546
// The scoring mechanism defined is as follows;
3647
//
@@ -136,36 +147,10 @@ func (ks *Keystore) CreateUser(_ *http.Request, args *CreateUserArgs, reply *Cre
136147
defer ks.lock.Unlock()
137148

138149
ks.log.Verbo("CreateUser called with %.*s", maxUserPassLen, args.Username)
139-
140-
if len(args.Username) > maxUserPassLen || len(args.Password) > maxUserPassLen {
141-
return errUserPassMaxLength
142-
}
143-
144-
if args.Username == "" {
145-
return errEmptyUsername
146-
}
147-
if usr, err := ks.getUser(args.Username); err == nil || usr != nil {
148-
return fmt.Errorf("user already exists: %s", args.Username)
149-
}
150-
151-
if zxcvbn.PasswordStrength(args.Password, nil).Score < requiredPassScore {
152-
return errWeakPassword
153-
}
154-
155-
usr := &User{}
156-
if err := usr.Initialize(args.Password); err != nil {
157-
return err
158-
}
159-
160-
usrBytes, err := ks.codec.Marshal(usr)
161-
if err != nil {
150+
if err := ks.AddUser(args.Username, args.Password); err != nil {
162151
return err
163152
}
164153

165-
if err := ks.userDB.Put([]byte(args.Username), usrBytes); err != nil {
166-
return err
167-
}
168-
ks.users[args.Username] = usr
169154
reply.Success = true
170155
return nil
171156
}
@@ -266,6 +251,10 @@ func (ks *Keystore) ImportUser(r *http.Request, args *ImportUserArgs, reply *Imp
266251

267252
ks.log.Verbo("ImportUser called for %s", args.Username)
268253

254+
if args.Username == "" {
255+
return errEmptyUsername
256+
}
257+
269258
if usr, err := ks.getUser(args.Username); err == nil || usr != nil {
270259
return fmt.Errorf("user already exists: %s", args.Username)
271260
}
@@ -399,3 +388,51 @@ func (ks *Keystore) GetDatabase(bID ids.ID, username, password string) (database
399388

400389
return encDB, nil
401390
}
391+
392+
// AddUser attempts to register this username and password as a new user of the
393+
// keystore.
394+
func (ks *Keystore) AddUser(username, password string) error {
395+
if len(username) > maxUserPassLen || len(password) > maxUserPassLen {
396+
return errUserPassMaxLength
397+
}
398+
399+
if username == "" {
400+
return errEmptyUsername
401+
}
402+
if usr, err := ks.getUser(username); err == nil || usr != nil {
403+
return fmt.Errorf("user already exists: %s", username)
404+
}
405+
406+
checkPass := password
407+
if len(password) > maxCheckedPassLen {
408+
checkPass = password[:maxCheckedPassLen]
409+
}
410+
411+
if zxcvbn.PasswordStrength(checkPass, nil).Score < requiredPassScore {
412+
return errWeakPassword
413+
}
414+
415+
usr := &User{}
416+
if err := usr.Initialize(password); err != nil {
417+
return err
418+
}
419+
420+
usrBytes, err := ks.codec.Marshal(usr)
421+
if err != nil {
422+
return err
423+
}
424+
425+
if err := ks.userDB.Put([]byte(username), usrBytes); err != nil {
426+
return err
427+
}
428+
ks.users[username] = usr
429+
430+
return nil
431+
}
432+
433+
// CreateTestKeystore returns a new keystore that can be utilized for testing
434+
func CreateTestKeystore(t *testing.T) *Keystore {
435+
ks := &Keystore{}
436+
ks.Initialize(logging.NoLog{}, memdb.New())
437+
return ks
438+
}

0 commit comments

Comments
 (0)