Skip to content

Commit

Permalink
use ticket validity age from config
Browse files Browse the repository at this point in the history
  • Loading branch information
itswisdomagain committed Aug 7, 2019
1 parent 6530be6 commit 3d56868
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 54 deletions.
102 changes: 56 additions & 46 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,33 +19,35 @@ import (
"github.com/decred/dcrd/dcrutil"
"github.com/decred/dcrd/hdkeychain"
"github.com/decred/dcrstakepool/internal/version"
"github.com/decred/dcrstakepool/v3api"
flags "github.com/jessevdk/go-flags"
)

const (
defaultBaseURL = "http://127.0.0.1:8000"
defaultClosePoolMsg = "The voting service is temporarily closed to new signups."
defaultConfigFilename = "dcrstakepool.conf"
defaultDataDirname = "data"
defaultLogLevel = "info"
defaultLogDirname = "logs"
defaultLogFilename = "dcrstakepool.log"
defaultCookieSecure = false
defaultDBHost = "localhost"
defaultDBName = "stakepool"
defaultDBPort = "3306"
defaultDBUser = "stakepool"
defaultListen = ":8000"
defaultPoolEmail = "[email protected]"
defaultPoolFees = 7.5
defaultPoolLink = "https://forum.decred.org/threads/rfp-6-setup-and-operate-10-stake-pools.1361/"
defaultPublicPath = "public"
defaultTemplatePath = "views"
defaultSMTPHost = ""
defaultMinServers = 2
defaultMaxVotedTickets = 1000
defaultDescription = ""
defaultDesignation = ""
defaultBaseURL = "http://127.0.0.1:8000"
defaultClosePoolMsg = "The voting service is temporarily closed to new signups."
defaultConfigFilename = "dcrstakepool.conf"
defaultDataDirname = "data"
defaultLogLevel = "info"
defaultLogDirname = "logs"
defaultLogFilename = "dcrstakepool.log"
defaultTicketChallengeMaxAge = 600
defaultCookieSecure = false
defaultDBHost = "localhost"
defaultDBName = "stakepool"
defaultDBPort = "3306"
defaultDBUser = "stakepool"
defaultListen = ":8000"
defaultPoolEmail = "[email protected]"
defaultPoolFees = 7.5
defaultPoolLink = "https://forum.decred.org/threads/rfp-6-setup-and-operate-10-stake-pools.1361/"
defaultPublicPath = "public"
defaultTemplatePath = "views"
defaultSMTPHost = ""
defaultMinServers = 2
defaultMaxVotedTickets = 1000
defaultDescription = ""
defaultDesignation = ""
)

var (
Expand Down Expand Up @@ -77,6 +79,7 @@ type config struct {
MemProfile string `long:"memprofile" description:"Write mem profile to the specified file"`
DebugLevel string `short:"d" long:"debuglevel" description:"Logging level for all subsystems {trace, debug, info, warn, error, critical} -- You may also specify <subsystem>=<level>,<subsystem2>=<level>,... to set the log level for individual subsystems -- Use show to list available subsystems"`
APISecret string `long:"apisecret" description:"Secret string used to encrypt API tokens."`
TicketChallengeMaxAge int64 `long:"ticketchallengemaxage" description:"Max age (in seconds) for API v3 ticket authentication timestamps. Max allowed value is 1800 (30 minutes)."`
BaseURL string `long:"baseurl" description:"BaseURL to use when sending links via email"`
// todo: can `ColdWalletExtPub` and `PoolFees` be read from stakepoold via rpc?
ColdWalletExtPub string `long:"coldwalletextpub" description:"The extended public key for addresses to which voting service user fees are sent."`
Expand Down Expand Up @@ -314,29 +317,30 @@ func newConfigParser(cfg *config, so *serviceOptions, options flags.Options) *fl
func loadConfig() (*config, []string, error) {
// Default config.
cfg := config{
BaseURL: defaultBaseURL,
ClosePool: false,
ClosePoolMsg: defaultClosePoolMsg,
ConfigFile: defaultConfigFile,
DebugLevel: defaultLogLevel,
DataDir: defaultDataDir,
LogDir: defaultLogDir,
CookieSecure: defaultCookieSecure,
DBHost: defaultDBHost,
DBName: defaultDBName,
DBPort: defaultDBPort,
DBUser: defaultDBUser,
Listen: defaultListen,
PoolEmail: defaultPoolEmail,
PoolFees: defaultPoolFees,
PoolLink: defaultPoolLink,
PublicPath: defaultPublicPath,
TemplatePath: defaultTemplatePath,
SMTPHost: defaultSMTPHost,
MinServers: defaultMinServers,
MaxVotedTickets: defaultMaxVotedTickets,
Description: defaultDescription,
Designation: defaultDesignation,
BaseURL: defaultBaseURL,
ClosePool: false,
ClosePoolMsg: defaultClosePoolMsg,
ConfigFile: defaultConfigFile,
DebugLevel: defaultLogLevel,
DataDir: defaultDataDir,
LogDir: defaultLogDir,
TicketChallengeMaxAge: defaultTicketChallengeMaxAge,
CookieSecure: defaultCookieSecure,
DBHost: defaultDBHost,
DBName: defaultDBName,
DBPort: defaultDBPort,
DBUser: defaultDBUser,
Listen: defaultListen,
PoolEmail: defaultPoolEmail,
PoolFees: defaultPoolFees,
PoolLink: defaultPoolLink,
PublicPath: defaultPublicPath,
TemplatePath: defaultTemplatePath,
SMTPHost: defaultSMTPHost,
MinServers: defaultMinServers,
MaxVotedTickets: defaultMaxVotedTickets,
Description: defaultDescription,
Designation: defaultDesignation,
}

// Service options which are only added on Windows.
Expand Down Expand Up @@ -474,6 +478,12 @@ func loadConfig() (*config, []string, error) {
return nil, nil, err
}

// Ensure ticket challenge max age is not greater than permitted maximum.
if cfg.TicketChallengeMaxAge > v3api.MaxTicketChallengeAge {
return nil, nil, fmt.Errorf("%s: Tickat challenge max age cannot be higher than %v",
funcName, v3api.MaxTicketChallengeAge)
}

// Validate profile port number
if cfg.Profile != "" {
profilePort, err := strconv.Atoi(cfg.Profile)
Expand Down
4 changes: 4 additions & 0 deletions sample-dcrstakepool.conf
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ designation=YourVSP
; Printed on the home screen under the VSP overview
description=Your VSP description

; Max age (in seconds) for API v3 ticket authentication timestamps.
; Max allowed value is 1800 (30 minutes).
; ticketchallengemaxage=600

; Secret string used to encrypt API and to generate CSRF tokens.
; Can use openssl rand -hex 32 to generate one.
;apisecret=
Expand Down
2 changes: 1 addition & 1 deletion server.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ func runMain() error {

api.Use(application.ApplyAPI)

v3Api := v3api.New(stakepooldConnMan)
v3Api := v3api.New(stakepooldConnMan, cfg.TicketChallengeMaxAge)
api.Use(v3Api.ApplyTicketAuth)

api.Handle("/api/v1/:command", application.APIHandler(controller.API))
Expand Down
8 changes: 4 additions & 4 deletions v3api/ticketauth.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const (
customAuthSignatureParam = "Signature"
customAuthTicketHashParam = "TicketHash"

authTimestampValiditySeconds = 30 * 10000000000
MaxTicketChallengeAge = 60 * 30 // 30 minutes
)

func (v3Api *V3API) validateTicketOwnership(authHeader string) (multiSigAddress string) {
Expand All @@ -42,7 +42,7 @@ func (v3Api *V3API) validateTicketOwnership(authHeader string) (multiSigAddress
// todo check if ticket belongs to this vsp

// check if timestamp is not yet expired
if err := validateTimestamp(timestamp); err != nil {
if err := validateTimestamp(timestamp, v3Api.ticketChallengeMaxAge); err != nil {
log.Warnf("ticket auth timestamp failed validation: %v", err)
return
}
Expand Down Expand Up @@ -97,7 +97,7 @@ func getAuthValueFromParam(paramKeyValue, key string) string {
return ""
}

func validateTimestamp(timestampMessage string) error {
func validateTimestamp(timestampMessage string, ticketChallengeMaxAge int64) error {
authTimestamp, err := strconv.Atoi(timestampMessage)
if err != nil {
return fmt.Errorf("invalid v3 auth request timestamp %v: %v", timestampMessage, err)
Expand All @@ -107,7 +107,7 @@ func validateTimestamp(timestampMessage string) error {

// Ensure that the auth timestamp is not in the future and is not more than 30 seconds into the past.
timestampDelta := time.Now().Unix() - int64(authTimestamp)
if timestampDelta < 0 || timestampDelta > authTimestampValiditySeconds {
if timestampDelta < 0 || timestampDelta > ticketChallengeMaxAge {
return fmt.Errorf("expired v3 auth request timestamp %v compared to %v", timestampMessage, time.Now().Unix())
}

Expand Down
8 changes: 5 additions & 3 deletions v3api/v3api.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ package v3api
import "github.com/decred/dcrstakepool/stakepooldclient"

type V3API struct {
stakepooldConnMan *stakepooldclient.StakepooldManager
stakepooldConnMan *stakepooldclient.StakepooldManager
ticketChallengeMaxAge int64
}

func New(stakepooldConnMan *stakepooldclient.StakepooldManager) *V3API {
func New(stakepooldConnMan *stakepooldclient.StakepooldManager, ticketChallengeMaxAge int64) *V3API {
return &V3API{
stakepooldConnMan: stakepooldConnMan,
stakepooldConnMan: stakepooldConnMan,
ticketChallengeMaxAge: ticketChallengeMaxAge,
}
}

0 comments on commit 3d56868

Please sign in to comment.