Add cookie support

©! I, Hugo Landau <hlandau@devever.net>, hereby licence these changes under the
©! licence with SHA256 hash
©! fd80a26fbb3f644af1fa994134446702932968519797227e07a1368dea80f0bc.
pull/18/head
Hugo Landau 7 years ago
parent aa564761b5
commit 1e6ccf7405

@ -31,13 +31,6 @@ var log, Log = xlog.New("ncdns.backend")
type Config struct {
NamecoinConn namecoin.Conn
// Username and password to use for connecting to the Namecoin JSON-RPC interface.
//RPCUsername string
//RPCPassword string
// hostname:port to use for connecting to the Namecoin JSON-RPC interface.
//RPCAddress string
// Maximum entries to permit in name cache. If zero, a default value is used.
CacheMaxEntries int

@ -1,13 +1,15 @@
package namecoin
// btcjson had to be modified a bit to get correct error reporting.
import "github.com/hlandauf/btcjson"
import "gopkg.in/hlandau/madns.v1/merr"
import extratypes "github.com/hlandau/ncbtcjsontypes"
import (
extratypes "github.com/hlandau/ncbtcjsontypes"
"github.com/hlandauf/btcjson"
"gopkg.in/hlandau/madns.v1/merr"
import "fmt"
import "expvar"
import "sync/atomic"
"expvar"
"fmt"
"sync/atomic"
)
var cQueryCalls = expvar.NewInt("ncdns.namecoin.numQueryCalls")
var cSyncCalls = expvar.NewInt("ncdns.namecoin.numSyncCalls")
@ -27,7 +29,29 @@ func newID() int32 {
type Conn struct {
Username string
Password string
Server string
// If set, this is called to obtain the username and password instead of
// using the Username and Password fields.
GetAuth func() (username, password string, err error)
Server string
}
func (nc *Conn) getAuth() (username string, password string, err error) {
if nc.GetAuth == nil {
return nc.Username, nc.Password, nil
}
return nc.GetAuth()
}
func (nc *Conn) rpcSend(cmd btcjson.Cmd) (btcjson.Reply, error) {
username, password, err := nc.getAuth()
if err != nil {
return btcjson.Reply{}, err
}
return btcjson.RpcSend(username, password, nc.Server, cmd)
}
// Query the Namecoin daemon for a Namecoin domain (e.g. d/example).
@ -42,7 +66,7 @@ func (nc *Conn) Query(name string) (v string, err error) {
return "", err
}
r, err := btcjson.RpcSend(nc.Username, nc.Password, nc.Server, cmd)
r, err := nc.rpcSend(cmd)
if err != nil {
return "", err
}
@ -81,7 +105,7 @@ func (nc *Conn) Sync(hash string, count int, wait bool) ([]extratypes.NameSyncEv
return nil, err
}
r, err := btcjson.RpcSend(nc.Username, nc.Password, nc.Server, cmd)
r, err := nc.rpcSend(cmd)
if err != nil {
return nil, err
}
@ -112,7 +136,7 @@ func (nc *Conn) CurHeight() (int, error) {
return 0, err
}
r, err := btcjson.RpcSend(nc.Username, nc.Password, nc.Server, cmd)
r, err := nc.rpcSend(cmd)
if err != nil {
return 0, err
}
@ -140,7 +164,7 @@ func (nc *Conn) Filter(regexp string, maxage, from, count int) (names []extratyp
return nil, err
}
r, err := btcjson.RpcSend(nc.Username, nc.Password, nc.Server, cmd)
r, err := nc.rpcSend(cmd)
if err != nil {
return nil, err
}
@ -168,7 +192,7 @@ func (nc *Conn) Scan(from string, count int) (names []extratypes.NameFilterItem,
return nil, err
}
r, err := btcjson.RpcSend(nc.Username, nc.Password, nc.Server, cmd)
r, err := nc.rpcSend(cmd)
if err != nil {
return nil, err
}

@ -0,0 +1,59 @@
package server
import (
"fmt"
"io/ioutil"
"os"
"strings"
"time"
)
func readCookieFile(path string) (username, password string, err error) {
b, err := ioutil.ReadFile(path)
if err != nil {
return
}
s := strings.TrimSpace(string(b))
parts := strings.SplitN(s, ":", 2)
if len(parts) != 2 {
err = fmt.Errorf("malformed cookie file")
return
}
username, password = parts[0], parts[1]
return
}
func cookieRetriever(path string) func() (username, password string, err error) {
lastCheckTime := time.Time{}
lastModTime := time.Time{}
curUsername, curPassword := "", ""
var curError error
doUpdate := func() {
if !lastCheckTime.IsZero() && time.Now().Before(lastCheckTime.Add(30*time.Second)) {
return
}
lastCheckTime = time.Now()
st, err := os.Stat(path)
if err != nil {
curError = err
return
}
modTime := st.ModTime()
if !modTime.Equal(lastModTime) {
lastModTime = modTime
curUsername, curPassword, curError = readCookieFile(path)
}
}
return func() (username, password string, err error) {
doUpdate()
return curUsername, curPassword, curError
}
}

@ -39,12 +39,13 @@ type Config struct {
ZonePublicKey string `default:"" usage:"Path to the DNSKEY ZSK public key file; if one is not specified, a temporary one is generated on startup and used only for the duration of that process"`
ZonePrivateKey string `default:"" usage:"Path to the ZSK's corresponding private key file"`
NamecoinRPCUsername string `default:"" usage:"Namecoin RPC username"`
NamecoinRPCPassword string `default:"" usage:"Namecoin RPC password"`
NamecoinRPCAddress string `default:"localhost:8336" usage:"Namecoin RPC server address"`
CacheMaxEntries int `default:"100" usage:"Maximum name cache entries"`
SelfName string `default:"" usage:"The FQDN of this nameserver. If empty, a psuedo-hostname is generated."`
SelfIP string `default:"127.127.127.127" usage:"The canonical IP address for this service"`
NamecoinRPCUsername string `default:"" usage:"Namecoin RPC username"`
NamecoinRPCPassword string `default:"" usage:"Namecoin RPC password"`
NamecoinRPCAddress string `default:"localhost:8336" usage:"Namecoin RPC server address"`
NamecoinRPCCookiePath string `default:"" usage:"Namecoin RPC cookie path (if set, used instead of password)"`
CacheMaxEntries int `default:"100" usage:"Maximum name cache entries"`
SelfName string `default:"" usage:"The FQDN of this nameserver. If empty, a psuedo-hostname is generated."`
SelfIP string `default:"127.127.127.127" usage:"The canonical IP address for this service"`
HTTPListenAddr string `default:"" usage:"Address for webserver to listen at (default: disabled)"`
@ -78,6 +79,10 @@ func New(cfg *Config) (s *Server, err error) {
},
}
if s.cfg.NamecoinRPCCookiePath != "" {
s.namecoinConn.GetAuth = cookieRetriever(s.cfg.NamecoinRPCCookiePath)
}
if s.cfg.CanonicalNameservers != "" {
s.cfg.canonicalNameservers = strings.Split(s.cfg.CanonicalNameservers, ",")
for i := range s.cfg.canonicalNameservers {

Loading…
Cancel
Save