Skip to content

Commit

Permalink
remove maxticketchallengeage config option, use constant value
Browse files Browse the repository at this point in the history
  • Loading branch information
itswisdomagain committed Sep 4, 2019
1 parent d3f119e commit d140358
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 126 deletions.
199 changes: 94 additions & 105 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,30 +26,27 @@ import (
)

const (
defaultBaseURL = "http://127.0.0.1:8000"
defaultClosePoolMsg = "The voting service is temporarily closed to new signups."
defaultConfigFilename = "dcrstakepool.conf"
defaultLogLevel = "info"
defaultLogDirname = "logs"
defaultLogFilename = "dcrstakepool.log"
defaultTicketChallengeMaxAge = 600 // 10 minutes
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 = ""
defaultMaxVotedTickets = 1000
defaultDescription = ""
defaultDesignation = ""

MaxTicketChallengeAge = 60 * 30 // 30 minutes
defaultBaseURL = "http://127.0.0.1:8000"
defaultClosePoolMsg = "The voting service is temporarily closed to new signups."
defaultConfigFilename = "dcrstakepool.conf"
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 = ""
defaultMaxVotedTickets = 1000
defaultDescription = ""
defaultDesignation = ""
)

var (
Expand All @@ -68,59 +65,58 @@ var runServiceCommand func(string) error
//
// See loadConfig for details on the configuration load process.
type config struct {
ShowVersion bool `short:"V" long:"version" description:"Display version information and exit"`
ConfigFile string `short:"C" long:"configfile" description:"Path to configuration file"`
DataDir string `short:"b" long:"datadir" description:"Deprecated. Unused, do not set."`
LogDir string `long:"logdir" description:"Directory to log output."`
Listen string `long:"listen" description:"Listen for connections on the specified interface/port (default all interfaces port: 9113, testnet: 19113)"`
TestNet bool `long:"testnet" description:"Use the test network"`
SimNet bool `long:"simnet" description:"Use the simulation test network"`
Profile string `long:"profile" description:"Enable HTTP profiling on given port -- NOTE port must be between 1024 and 65536"`
CPUProfile string `long:"cpuprofile" description:"Write CPU profile to the specified file"`
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"`
ColdWalletExtPub string `long:"coldwalletextpub" description:"The extended public key for addresses to which voting service user fees are sent."`
ClosePool bool `long:"closepool" description:"Disable user registration actions (sign-ups and submitting addresses)"`
ClosePoolMsg string `long:"closepoolmsg" description:"Message to display when closepool is set."`
CookieSecret string `long:"cookiesecret" description:"Secret string used to encrypt session data."`
CookieSecure bool `long:"cookiesecure" description:"Set whether cookies can be sent in clear text or not."`
DBHost string `long:"dbhost" description:"Hostname for database connection"`
DBUser string `long:"dbuser" description:"Username for database connection"`
DBPassword string `long:"dbpassword" description:"Password for database connection"`
DBPort string `long:"dbport" description:"Port for database connection"`
DBName string `long:"dbname" description:"Name of database"`
PublicPath string `long:"publicpath" description:"Path to the public folder which contains css/fonts/images/javascript."`
TemplatePath string `long:"templatepath" description:"Path to the views folder which contains html files."`
PoolEmail string `long:"poolemail" description:"Email address to for support inquiries"`
PoolFees float64 `long:"poolfees" description:"The per-ticket fees the user must send to the pool with their tickets"`
PoolLink string `long:"poollink" description:"URL for support inquiries such as forum, IRC, etc"`
RealIPHeader string `long:"realipheader" description:"The name of an HTTP request header containing the actual remote client IP address, typically set by a reverse proxy. An empty string (default) indicates to use net/Request.RemodeAddr."`
SMTPFrom string `long:"smtpfrom" description:"From address to use on outbound mail"`
SMTPHost string `long:"smtphost" description:"SMTP hostname/ip and port, e.g. mail.example.com:25"`
SMTPUsername string `long:"smtpusername" description:"SMTP username for authentication if required"`
SMTPPassword string `long:"smtppassword" description:"SMTP password for authentication if required"`
UseSMTPS bool `long:"usesmtps" description:"Connect to the SMTP server using smtps."`
SMTPSkipVerify bool `long:"smtpskipverify" description:"Skip SMTP TLS cert verification. Will only skip if SMTPCert is empty"`
SMTPCert string `long:"smtpcert" description:"Path for the smtp certificate file"`
SystemCerts *x509.CertPool
StakepooldHosts []string `long:"stakepooldhosts" description:"Hostnames for stakepoold servers"`
StakepooldCerts []string `long:"stakepooldcerts" description:"Certificate paths for stakepoold servers"`
WalletHosts []string `long:"wallethosts" description:"Deprecated: dcrstakepool no longer connects to dcrwallet"`
WalletUsers []string `long:"walletusers" description:"Deprecated: dcrstakepool no longer connects to dcrwallet"`
WalletPasswords []string `long:"walletpasswords" description:"Deprecated: dcrstakepool no longer connects to dcrwallet"`
WalletCerts []string `long:"walletcerts" description:"Deprecated: dcrstakepool no longer connects to dcrwallet"`
VotingWalletExtPub string `long:"votingwalletextpub" description:"The extended public key of the default account of the voting wallet"`
AdminIPs []string `long:"adminips" description:"Expected admin host"`
AdminUserIDs []string `long:"adminuserids" description:"User IDs of users who are allowed to access administrative functions."`
MinServers int `long:"minservers" description:"Deprecated: Do not use. Minimum of 2 servers are required when running on mainnet. Testnet and simnet require minimum 1."`
EnableStakepoold bool `long:"enablestakepoold" description:"Deprecated: Do not use. Stakepoold is required."`
MaxVotedAge int64 `long:"maxvotedage" description:"Deprecated: Use maxvotedtickets instead"`
MaxVotedTickets int `long:"maxvotedtickets" description:"Maximum number of voted tickets to show on tickets page."`
Description string `long:"description" description:"Operators own description of their VSP"`
Designation string `long:"designation" description:"VSP designation (eg. Alpha, Bravo, etc)"`
ShowVersion bool `short:"V" long:"version" description:"Display version information and exit"`
ConfigFile string `short:"C" long:"configfile" description:"Path to configuration file"`
DataDir string `short:"b" long:"datadir" description:"Deprecated. Unused, do not set."`
LogDir string `long:"logdir" description:"Directory to log output."`
Listen string `long:"listen" description:"Listen for connections on the specified interface/port (default all interfaces port: 9113, testnet: 19113)"`
TestNet bool `long:"testnet" description:"Use the test network"`
SimNet bool `long:"simnet" description:"Use the simulation test network"`
Profile string `long:"profile" description:"Enable HTTP profiling on given port -- NOTE port must be between 1024 and 65536"`
CPUProfile string `long:"cpuprofile" description:"Write CPU profile to the specified file"`
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."`
BaseURL string `long:"baseurl" description:"BaseURL to use when sending links via email"`
ColdWalletExtPub string `long:"coldwalletextpub" description:"The extended public key for addresses to which voting service user fees are sent."`
ClosePool bool `long:"closepool" description:"Disable user registration actions (sign-ups and submitting addresses)"`
ClosePoolMsg string `long:"closepoolmsg" description:"Message to display when closepool is set."`
CookieSecret string `long:"cookiesecret" description:"Secret string used to encrypt session data."`
CookieSecure bool `long:"cookiesecure" description:"Set whether cookies can be sent in clear text or not."`
DBHost string `long:"dbhost" description:"Hostname for database connection"`
DBUser string `long:"dbuser" description:"Username for database connection"`
DBPassword string `long:"dbpassword" description:"Password for database connection"`
DBPort string `long:"dbport" description:"Port for database connection"`
DBName string `long:"dbname" description:"Name of database"`
PublicPath string `long:"publicpath" description:"Path to the public folder which contains css/fonts/images/javascript."`
TemplatePath string `long:"templatepath" description:"Path to the views folder which contains html files."`
PoolEmail string `long:"poolemail" description:"Email address to for support inquiries"`
PoolFees float64 `long:"poolfees" description:"The per-ticket fees the user must send to the pool with their tickets"`
PoolLink string `long:"poollink" description:"URL for support inquiries such as forum, IRC, etc"`
RealIPHeader string `long:"realipheader" description:"The name of an HTTP request header containing the actual remote client IP address, typically set by a reverse proxy. An empty string (default) indicates to use net/Request.RemodeAddr."`
SMTPFrom string `long:"smtpfrom" description:"From address to use on outbound mail"`
SMTPHost string `long:"smtphost" description:"SMTP hostname/ip and port, e.g. mail.example.com:25"`
SMTPUsername string `long:"smtpusername" description:"SMTP username for authentication if required"`
SMTPPassword string `long:"smtppassword" description:"SMTP password for authentication if required"`
UseSMTPS bool `long:"usesmtps" description:"Connect to the SMTP server using smtps."`
SMTPSkipVerify bool `long:"smtpskipverify" description:"Skip SMTP TLS cert verification. Will only skip if SMTPCert is empty"`
SMTPCert string `long:"smtpcert" description:"Path for the smtp certificate file"`
SystemCerts *x509.CertPool
StakepooldHosts []string `long:"stakepooldhosts" description:"Hostnames for stakepoold servers"`
StakepooldCerts []string `long:"stakepooldcerts" description:"Certificate paths for stakepoold servers"`
WalletHosts []string `long:"wallethosts" description:"Deprecated: dcrstakepool no longer connects to dcrwallet"`
WalletUsers []string `long:"walletusers" description:"Deprecated: dcrstakepool no longer connects to dcrwallet"`
WalletPasswords []string `long:"walletpasswords" description:"Deprecated: dcrstakepool no longer connects to dcrwallet"`
WalletCerts []string `long:"walletcerts" description:"Deprecated: dcrstakepool no longer connects to dcrwallet"`
VotingWalletExtPub string `long:"votingwalletextpub" description:"The extended public key of the default account of the voting wallet"`
AdminIPs []string `long:"adminips" description:"Expected admin host"`
AdminUserIDs []string `long:"adminuserids" description:"User IDs of users who are allowed to access administrative functions."`
MinServers int `long:"minservers" description:"Deprecated: Do not use. Minimum of 2 servers are required when running on mainnet. Testnet and simnet require minimum 1."`
EnableStakepoold bool `long:"enablestakepoold" description:"Deprecated: Do not use. Stakepoold is required."`
MaxVotedAge int64 `long:"maxvotedage" description:"Deprecated: Use maxvotedtickets instead"`
MaxVotedTickets int `long:"maxvotedtickets" description:"Maximum number of voted tickets to show on tickets page."`
Description string `long:"description" description:"Operators own description of their VSP"`
Designation string `long:"designation" description:"VSP designation (eg. Alpha, Bravo, etc)"`
}

// serviceOptions defines the configuration options for the daemon as a service
Expand Down Expand Up @@ -317,28 +313,27 @@ 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,
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,
MaxVotedTickets: defaultMaxVotedTickets,
Description: defaultDescription,
Designation: defaultDesignation,
BaseURL: defaultBaseURL,
ClosePool: false,
ClosePoolMsg: defaultClosePoolMsg,
ConfigFile: defaultConfigFile,
DebugLevel: defaultLogLevel,
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,
MaxVotedTickets: defaultMaxVotedTickets,
Description: defaultDescription,
Designation: defaultDesignation,
}

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

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

// Validate profile port number
if cfg.Profile != "" {
profilePort, err := strconv.Atoi(cfg.Profile)
Expand Down
4 changes: 0 additions & 4 deletions sample-dcrstakepool.conf
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@ adminips=127.0.0.1
; Multiple values can be used and are separated by a comma.
;adminuserids=1,2,3

; Max age (in seconds) for per-ticket api 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 @@ -63,7 +63,7 @@ func runMain() error {

var application = &system.Application{}

application.Init(cfg.APISecret, cfg.TicketChallengeMaxAge, cfg.BaseURL, cfg.CookieSecret,
application.Init(cfg.APISecret, cfg.BaseURL, cfg.CookieSecret,
cfg.CookieSecure, cfg.DBHost, cfg.DBName, cfg.DBPassword, cfg.DBPort,
cfg.DBUser)
if application.DbMap == nil {
Expand Down
22 changes: 11 additions & 11 deletions system/api-auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package system
import (
"encoding/base64"
"fmt"
"math"
"strconv"
"strings"
"time"
Expand All @@ -12,6 +13,10 @@ import (
"github.com/dgrijalva/jwt-go"
)

// maxTicketChallengeAge is the maximum number of seconds into the past
// or future required for a ticket auth timestamp value to be considered valid.
const maxTicketChallengeAge = 60

func (application *Application) validateToken(authHeader string) (int64, string) {
apitoken := strings.TrimPrefix(authHeader, "Bearer ")

Expand Down Expand Up @@ -51,16 +56,12 @@ func (application *Application) validateTicketOwnership(authHeader string) (mult
return
}

// Ensure that the auth timestamp
// - is not more than 5 minutes into the future
// - is not more than 30 seconds into the past
// Ensure that the auth timestamp is not more than
// the permitted number of seconds into the past and future.
timestampDelta := time.Now().Unix() - int64(authTimestamp)
if timestampDelta < -300 {
// more than 5 minutes into the future
authValidationFailureReason = "invalid (future) timestamp"
return
} else if timestampDelta > application.TicketChallengeMaxAge {
authValidationFailureReason = fmt.Sprintf("expired ticket auth timestamp value %v", timestamp)
if math.Abs(float64(timestampDelta)) > maxTicketChallengeAge {
authValidationFailureReason = fmt.Sprintf("expired or invalid ticket auth timestamp value %v",
timestamp)
return
}

Expand All @@ -72,8 +73,7 @@ func (application *Application) validateTicketOwnership(authHeader string) (mult
}

// Mark this timestamp signature as used to prevent subsequent reuse.
challengeExpiresIn := application.TicketChallengeMaxAge - timestampDelta
application.ProcessedTicketChallenges.AddChallenge(timestampSignature, challengeExpiresIn)
application.ProcessedTicketChallenges.AddChallenge(timestampSignature, maxTicketChallengeAge)

// todo check if ticket belongs to this vsp

Expand Down
Loading

0 comments on commit d140358

Please sign in to comment.