Browse Source

Config cleanup, specify host and port

make_cert_optional
Oliver Gugger 6 years ago
parent
commit
26671efa30
No known key found for this signature in database GPG Key ID: 8E4256593F177720
  1. 27
      README.md
  2. 338
      config.go
  3. 54
      zapconnect.go

27
README.md

@ -19,15 +19,20 @@ zapconnect
## Application Options ## Application Options
``` ```
-i, --localip Use local ip instead of public ip. -i, --localip Include local ip in QRCode
-l, --localhost Use 127.0.0.1 for ip. -l, --localhost Use 127.0.0.1 for ip
-j, --json Display json instead of a QRCode. -h, --host= Use specific host name
-o, --image Output QRCode to file. -p, --port= Use this port (default: 10009)
--lnddir= The base directory that contains lnd's data, logs, configuration -o, --image Output QRCode to file
file, etc. --invoice Use invoice macaroon
--configfile= Path to configuration file --readonly Use readonly macaroon
-b, --datadir= The directory to store lnd's data within --lnddir= The base directory that contains lnd's data, logs, configuration
--tlscertpath= Path to write the TLS certificate for lnd's RPC and REST services file, etc.
--adminmacaroonpath= Path to write the admin macaroon for lnd's RPC and REST services --configfile= Path to configuration file
if it doesn't exist -b, --datadir= The directory to find lnd's data within
--tlscertpath= Path to read the TLS certificate from
--adminmacaroonpath= Path to read the admin macaroon from
--readonlymacaroonpath= Path to read the read-only macaroon from
--invoicemacaroonpath= Path to read the invoice-only macaroon from
``` ```

338
config.go

@ -6,244 +6,83 @@ package main
import ( import (
"fmt" "fmt"
"net"
"os" "os"
"os/user" "os/user"
"path/filepath" "path/filepath"
"strconv"
"strings" "strings"
"time"
"github.com/btcsuite/btcutil" "github.com/btcsuite/btcutil"
flags "github.com/jessevdk/go-flags" "github.com/jessevdk/go-flags"
"github.com/lightningnetwork/lnd/htlcswitch/hodl"
"github.com/lightningnetwork/lnd/lncfg"
"github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/tor" "github.com/lightningnetwork/lnd/tor"
) )
const ( const (
defaultConfigFilename = "lnd.conf" defaultConfigFilename = "lnd.conf"
defaultDataDirname = "data" defaultDataDirname = "data"
defaultChainSubDirname = "chain" defaultChainSubDirname = "chain"
defaultGraphSubDirname = "graph" defaultTLSCertFilename = "tls.cert"
defaultTLSCertFilename = "tls.cert" defaultAdminMacFilename = "admin.macaroon"
defaultTLSKeyFilename = "tls.key" defaultReadMacFilename = "readonly.macaroon"
defaultAdminMacFilename = "admin.macaroon" defaultInvoiceMacFilename = "invoice.macaroon"
defaultReadMacFilename = "readonly.macaroon" defaultRPCPort = 10009
defaultInvoiceMacFilename = "invoice.macaroon"
defaultLogLevel = "info"
defaultLogDirname = "logs"
defaultLogFilename = "lnd.log"
defaultRPCPort = 10009
defaultRESTPort = 8080
defaultPeerPort = 9735
defaultRPCHost = "localhost"
defaultMaxPendingChannels = 1
defaultNoSeedBackup = false
defaultTrickleDelay = 30 * 1000
defaultInactiveChanTimeout = 20 * time.Minute
defaultMaxLogFiles = 3
defaultMaxLogFileSize = 10
defaultTorSOCKSPort = 9050
defaultTorDNSHost = "soa.nodes.lightning.directory"
defaultTorDNSPort = 53
defaultTorControlPort = 9051
defaultTorV2PrivateKeyFilename = "v2_onion_private_key"
defaultTorV3PrivateKeyFilename = "v3_onion_private_key"
defaultBroadcastDelta = 10
// minTimeLockDelta is the minimum timelock we require for incoming
// HTLCs on our channels.
minTimeLockDelta = 4
defaultAlias = ""
defaultColor = "#3399FF"
) )
var ( var (
defaultLndDir = btcutil.AppDataDir("lnd", false) defaultLndDir = btcutil.AppDataDir("lnd", false)
defaultConfigFile = filepath.Join(defaultLndDir, defaultConfigFilename) defaultConfigFile = filepath.Join(defaultLndDir, defaultConfigFilename)
defaultDataDir = filepath.Join(defaultLndDir, defaultDataDirname) defaultDataDir = filepath.Join(defaultLndDir, defaultDataDirname)
defaultLogDir = filepath.Join(defaultLndDir, defaultLogDirname)
defaultTLSCertPath = filepath.Join(defaultLndDir, defaultTLSCertFilename) defaultTLSCertPath = filepath.Join(defaultLndDir, defaultTLSCertFilename)
defaultTLSKeyPath = filepath.Join(defaultLndDir, defaultTLSKeyFilename)
defaultBtcdDir = btcutil.AppDataDir("btcd", false)
defaultBtcdRPCCertFile = filepath.Join(defaultBtcdDir, "rpc.cert")
defaultLtcdDir = btcutil.AppDataDir("ltcd", false)
defaultLtcdRPCCertFile = filepath.Join(defaultLtcdDir, "rpc.cert")
defaultBitcoindDir = btcutil.AppDataDir("bitcoin", false)
defaultLitecoindDir = btcutil.AppDataDir("litecoin", false)
defaultTorSOCKS = net.JoinHostPort("localhost", strconv.Itoa(defaultTorSOCKSPort))
defaultTorDNS = net.JoinHostPort(defaultTorDNSHost, strconv.Itoa(defaultTorDNSPort))
defaultTorControl = net.JoinHostPort("localhost", strconv.Itoa(defaultTorControlPort))
) )
type chainConfig struct { type chainConfig struct {
Active bool `long:"active" description:"If the chain should be active or not."` Active bool `long:"active" description:"If the chain should be active or not"`
ChainDir string `long:"chaindir" description:"The directory to store the chain's data within."`
Node string `long:"node" description:"The blockchain interface to use." choice:"btcd" choice:"bitcoind" choice:"neutrino" choice:"ltcd" choice:"litecoind"`
MainNet bool `long:"mainnet" description:"Use the main network"` MainNet bool `long:"mainnet" description:"Use the main network"`
TestNet3 bool `long:"testnet" description:"Use the test network"` TestNet3 bool `long:"testnet" description:"Use the test network"`
SimNet bool `long:"simnet" description:"Use the simulation test network"` SimNet bool `long:"simnet" description:"Use the simulation test network"`
RegTest bool `long:"regtest" description:"Use the regression test network"` RegTest bool `long:"regtest" description:"Use the regression test network"`
DefaultNumChanConfs int `long:"defaultchanconfs" description:"The default number of confirmations a channel must have before it's considered open. If this is not set, we will scale the value according to the channel size."`
DefaultRemoteDelay int `long:"defaultremotedelay" description:"The default number of blocks we will require our channel counterparty to wait before accessing its funds in case of unilateral close. If this is not set, we will scale the value according to the channel size."`
MinHTLC lnwire.MilliSatoshi `long:"minhtlc" description:"The smallest HTLC we are willing to forward on our channels, in millisatoshi"`
BaseFee lnwire.MilliSatoshi `long:"basefee" description:"The base fee in millisatoshi we will charge for forwarding payments on our channels"`
FeeRate lnwire.MilliSatoshi `long:"feerate" description:"The fee rate used when forwarding payments on our channels. The total fee charged is basefee + (amount * feerate / 1000000), where amount is the forwarded amount."`
TimeLockDelta uint32 `long:"timelockdelta" description:"The CLTV delta we will subtract from a forwarded HTLC's timelock value"`
}
type neutrinoConfig struct {
AddPeers []string `short:"a" long:"addpeer" description:"Add a peer to connect with at startup"`
ConnectPeers []string `long:"connect" description:"Connect only to the specified peers at startup"`
MaxPeers int `long:"maxpeers" description:"Max number of inbound and outbound peers"`
BanDuration time.Duration `long:"banduration" description:"How long to ban misbehaving peers. Valid time units are {s, m, h}. Minimum 1 second"`
BanThreshold uint32 `long:"banthreshold" description:"Maximum allowed ban score before disconnecting and banning misbehaving peers."`
}
type btcdConfig struct {
Dir string `long:"dir" description:"The base directory that contains the node's data, logs, configuration file, etc."`
RPCHost string `long:"rpchost" description:"The daemon's rpc listening address. If a port is omitted, then the default port for the selected chain parameters will be used."`
RPCUser string `long:"rpcuser" description:"Username for RPC connections"`
RPCPass string `long:"rpcpass" default-mask:"-" description:"Password for RPC connections"`
RPCCert string `long:"rpccert" description:"File containing the daemon's certificate file"`
RawRPCCert string `long:"rawrpccert" description:"The raw bytes of the daemon's PEM-encoded certificate chain which will be used to authenticate the RPC connection."`
}
type bitcoindConfig struct {
Dir string `long:"dir" description:"The base directory that contains the node's data, logs, configuration file, etc."`
RPCHost string `long:"rpchost" description:"The daemon's rpc listening address. If a port is omitted, then the default port for the selected chain parameters will be used."`
RPCUser string `long:"rpcuser" description:"Username for RPC connections"`
RPCPass string `long:"rpcpass" default-mask:"-" description:"Password for RPC connections"`
ZMQPubRawBlock string `long:"zmqpubrawblock" description:"The address listening for ZMQ connections to deliver raw block notifications"`
ZMQPubRawTx string `long:"zmqpubrawtx" description:"The address listening for ZMQ connections to deliver raw transaction notifications"`
}
type autoPilotConfig struct {
Active bool `long:"active" description:"If the autopilot agent should be active or not."`
MaxChannels int `long:"maxchannels" description:"The maximum number of channels that should be created"`
Allocation float64 `long:"allocation" description:"The percentage of total funds that should be committed to automatic channel establishment"`
MinChannelSize int64 `long:"minchansize" description:"The smallest channel that the autopilot agent should create"`
MaxChannelSize int64 `long:"maxchansize" description:"The largest channel that the autopilot agent should create"`
Private bool `long:"private" description:"Whether the channels created by the autopilot agent should be private or not. Private channels won't be announced to the network."`
MinConfs int32 `long:"minconfs" description:"The minimum number of confirmations each of your inputs in funding transactions created by the autopilot agent must have."`
}
type torConfig struct {
Active bool `long:"active" description:"Allow outbound and inbound connections to be routed through Tor"`
SOCKS string `long:"socks" description:"The host:port that Tor's exposed SOCKS5 proxy is listening on"`
DNS string `long:"dns" description:"The DNS server as host:port that Tor will use for SRV queries - NOTE must have TCP resolution enabled"`
StreamIsolation bool `long:"streamisolation" description:"Enable Tor stream isolation by randomizing user credentials for each connection."`
Control string `long:"control" description:"The host:port that Tor is listening on for Tor control connections"`
V2 bool `long:"v2" description:"Automatically set up a v2 onion service to listen for inbound connections"`
V3 bool `long:"v3" description:"Automatically set up a v3 onion service to listen for inbound connections"`
PrivateKeyPath string `long:"privatekeypath" description:"The path to the private key of the onion service being created"`
} }
type zapConnectConfig struct { type zapConnectConfig struct {
LocalIp bool `short:"i" long:"localip" description:"Include local ip in QRCode."` LocalIp bool `short:"i" long:"localip" description:"Include local ip in QRCode"`
Localhost bool `short:"l" long:"localhost" description:"Use 127.0.0.1 for ip."` Localhost bool `short:"l" long:"localhost" description:"Use 127.0.0.1 for ip"`
Json bool `short:"j" long:"json" description:"Generate json instead of a QRCode."` Host string `short:"h" long:"host" description:"Use specific host name"`
Image bool `short:"o" long:"image" description:"Output QRCode to file."` Port uint16 `short:"p" long:"port" description:"Use this port"`
Invoice bool `long:"invoice" description:"use invoice macaroon"` Json bool `short:"j" long:"json" description:"Generate json instead of a QRCode"`
Readonly bool `long:"readonly" description:"use readonly macaroon"` Image bool `short:"o" long:"image" description:"Output QRCode to file"`
Invoice bool `long:"invoice" description:"use invoice macaroon"`
Readonly bool `long:"readonly" description:"use readonly macaroon"`
} }
// config defines the configuration options for lnd. // config defines the configuration options for zapconnect.
// //
// See loadConfig for further details regarding the configuration // See loadConfig for further details regarding the configuration
// loading+parsing process. // loading+parsing process.
type config struct { type config struct {
ZapConnect *zapConnectConfig `group:"ZapConnect"` ZapConnect *zapConnectConfig `group:"ZapConnect"`
ShowVersion bool `short:"V" long:"version" description:"Display version information and exit"`
LndDir string `long:"lnddir" description:"The base directory that contains lnd's data, logs, configuration file, etc."` LndDir string `long:"lnddir" description:"The base directory that contains lnd's data, logs, configuration file, etc."`
ConfigFile string `long:"C" long:"configfile" description:"Path to configuration file"` ConfigFile string `long:"C" long:"configfile" description:"Path to configuration file"`
DataDir string `short:"b" long:"datadir" description:"The directory to store lnd's data within"` DataDir string `short:"b" long:"datadir" description:"The directory to find lnd's data within"`
TLSCertPath string `long:"tlscertpath" description:"Path to write the TLS certificate for lnd's RPC and REST services"` TLSCertPath string `long:"tlscertpath" description:"Path to read the TLS certificate from"`
TLSKeyPath string `long:"tlskeypath" description:"Path to write the TLS private key for lnd's RPC and REST services"` AdminMacPath string `long:"adminmacaroonpath" description:"Path to read the admin macaroon from"`
TLSExtraIP string `long:"tlsextraip" description:"Adds an extra ip to the generated certificate"` ReadMacPath string `long:"readonlymacaroonpath" description:"Path to read the read-only macaroon from"`
TLSExtraDomain string `long:"tlsextradomain" description:"Adds an extra domain to the generated certificate"` InvoiceMacPath string `long:"invoicemacaroonpath" description:"Path to read the invoice-only macaroon from"`
NoMacaroons bool `long:"no-macaroons" description:"Disable macaroon authentication"`
AdminMacPath string `long:"adminmacaroonpath" description:"Path to write the admin macaroon for lnd's RPC and REST services if it doesn't exist"` Bitcoin *chainConfig `group:"Bitcoin" namespace:"bitcoin"`
ReadMacPath string `long:"readonlymacaroonpath" description:"Path to write the read-only macaroon for lnd's RPC and REST services if it doesn't exist"` Litecoin *chainConfig `group:"Litecoin" namespace:"litecoin"`
InvoiceMacPath string `long:"invoicemacaroonpath" description:"Path to the invoice-only macaroon for lnd's RPC and REST services if it doesn't exist"`
LogDir string `long:"logdir" description:"Directory to log output."` // The following lines we only need to be able to parse the
MaxLogFiles int `long:"maxlogfiles" description:"Maximum logfiles to keep (0 for no rotation)"` // configuration INI file without errors. The content will be ignored.
MaxLogFileSize int `long:"maxlogfilesize" description:"Maximum logfile size in MB"` BtcdMode *chainConfig `hidden:"true" group:"btcd" namespace:"btcd"`
BitcoindMode *chainConfig `hidden:"true" group:"bitcoind" namespace:"bitcoind"`
// We'll parse these 'raw' string arguments into real net.Addrs in the NeutrinoMode *chainConfig `hidden:"true" group:"neutrino" namespace:"neutrino"`
// loadConfig function. We need to expose the 'raw' strings so the LtcdMode *chainConfig `hidden:"true" group:"ltcd" namespace:"ltcd"`
// command line library can access them. LitecoindMode *chainConfig `hidden:"true" group:"litecoind" namespace:"litecoind"`
// Only the parsed net.Addrs should be used! Autopilot *chainConfig `hidden:"true" group:"Autopilot" namespace:"autopilot"`
RawRPCListeners []string `long:"rpclisten" description:"Add an interface/port/socket to listen for RPC connections"` Tor *chainConfig `hidden:"true" group:"Tor" namespace:"tor"`
RawRESTListeners []string `long:"restlisten" description:"Add an interface/port/socket to listen for REST connections"` Hodl *chainConfig `hidden:"true" group:"hodl" namespace:"hodl"`
RawListeners []string `long:"listen" description:"Add an interface/port to listen for peer connections"`
RawExternalIPs []string `long:"externalip" description:"Add an ip:port to the list of local addresses we claim to listen on to peers. If a port is not specified, the default (9735) will be used regardless of other parameters"`
RPCListeners []net.Addr
RESTListeners []net.Addr
Listeners []net.Addr
ExternalIPs []net.Addr
DisableListen bool `long:"nolisten" description:"Disable listening for incoming peer connections"`
NAT bool `long:"nat" description:"Toggle NAT traversal support (using either UPnP or NAT-PMP) to automatically advertise your external IP address to the network -- NOTE this does not support devices behind multiple NATs"`
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"`
CPUProfile string `long:"cpuprofile" description:"Write CPU profile to the specified file"`
Profile string `long:"profile" description:"Enable HTTP profiling on given port -- NOTE port must be between 1024 and 65535"`
DebugHTLC bool `long:"debughtlc" description:"Activate the debug htlc mode. With the debug HTLC mode, all payments sent use a pre-determined R-Hash. Additionally, all HTLCs sent to a node with the debug HTLC R-Hash are immediately settled in the next available state transition."`
UnsafeDisconnect bool `long:"unsafe-disconnect" description:"Allows the rpcserver to intentionally disconnect from peers with open channels. USED FOR TESTING ONLY."`
UnsafeReplay bool `long:"unsafe-replay" description:"Causes a link to replay the adds on its commitment txn after starting up, this enables testing of the sphinx replay logic."`
MaxPendingChannels int `long:"maxpendingchannels" description:"The maximum number of incoming pending channels permitted per peer."`
Bitcoin *chainConfig `group:"Bitcoin" namespace:"bitcoin"`
BtcdMode *btcdConfig `group:"btcd" namespace:"btcd"`
BitcoindMode *bitcoindConfig `group:"bitcoind" namespace:"bitcoind"`
NeutrinoMode *neutrinoConfig `group:"neutrino" namespace:"neutrino"`
Litecoin *chainConfig `group:"Litecoin" namespace:"litecoin"`
LtcdMode *btcdConfig `group:"ltcd" namespace:"ltcd"`
LitecoindMode *bitcoindConfig `group:"litecoind" namespace:"litecoind"`
Autopilot *autoPilotConfig `group:"Autopilot" namespace:"autopilot"`
Tor *torConfig `group:"Tor" namespace:"tor"`
Hodl *hodl.Config `group:"hodl" namespace:"hodl"`
NoNetBootstrap bool `long:"nobootstrap" description:"If true, then automatic network bootstrapping will not be attempted."`
NoSeedBackup bool `long:"noseedbackup" description:"If true, NO SEED WILL BE EXPOSED AND THE WALLET WILL BE ENCRYPTED USING THE DEFAULT PASSPHRASE -- EVER. THIS FLAG IS ONLY FOR TESTING AND IS BEING DEPRECATED."`
TrickleDelay int `long:"trickledelay" description:"Time in milliseconds between each release of announcements to the network"`
InactiveChanTimeout time.Duration `long:"inactivechantimeout" description:"If a channel has been inactive for the set time, send a ChannelUpdate disabling it."`
Alias string `long:"alias" description:"The node alias. Used as a moniker by peers and intelligence services"`
Color string `long:"color" description:"The color of the node in hex format (i.e. '#3399FF'). Used to customize node appearance in intelligence services"`
MinChanSize int64 `long:"minchansize" description:"The smallest channel size (in satoshis) that we should accept. Incoming channels smaller than this will be rejected"`
NoChanUpdates bool `long:"nochanupdates" description:"If specified, lnd will not request real-time channel updates from connected peers. This option should be used by routing nodes to save bandwidth."`
RejectPush bool `long:"rejectpush" description:"If true, lnd will not accept channel opening requests with non-zero push amounts. This should prevent accidental pushes to merchant nodes."`
net tor.Net net tor.Net
// Routing *routing.Conf `group:"routing" namespace:"routing"`
} }
// loadConfig initializes and parses the config using a config file and command // loadConfig initializes and parses the config using a config file and command
@ -256,66 +95,14 @@ type config struct {
// 4) Parse CLI options and overwrite/add any specified options // 4) Parse CLI options and overwrite/add any specified options
func loadConfig() (*config, error) { func loadConfig() (*config, error) {
defaultCfg := config{ defaultCfg := config{
LndDir: defaultLndDir, ZapConnect: &zapConnectConfig{
ConfigFile: defaultConfigFile, Port: defaultRPCPort,
DataDir: defaultDataDir,
DebugLevel: defaultLogLevel,
TLSCertPath: defaultTLSCertPath,
TLSKeyPath: defaultTLSKeyPath,
LogDir: defaultLogDir,
MaxLogFiles: defaultMaxLogFiles,
MaxLogFileSize: defaultMaxLogFileSize,
Bitcoin: &chainConfig{
MinHTLC: 0,
BaseFee: 0,
FeeRate: 0,
TimeLockDelta: 0,
Node: "btcd",
},
BtcdMode: &btcdConfig{
Dir: defaultBtcdDir,
RPCHost: defaultRPCHost,
RPCCert: defaultBtcdRPCCertFile,
}, },
BitcoindMode: &bitcoindConfig{ LndDir: defaultLndDir,
Dir: defaultBitcoindDir, ConfigFile: defaultConfigFile,
RPCHost: defaultRPCHost, DataDir: defaultDataDir,
}, TLSCertPath: defaultTLSCertPath,
Litecoin: &chainConfig{ net: &tor.ClearNet{},
MinHTLC: 0,
BaseFee: 0,
FeeRate: 0,
TimeLockDelta: 0,
Node: "ltcd",
},
LtcdMode: &btcdConfig{
Dir: defaultLtcdDir,
RPCHost: defaultRPCHost,
RPCCert: defaultLtcdRPCCertFile,
},
LitecoindMode: &bitcoindConfig{
Dir: defaultLitecoindDir,
RPCHost: defaultRPCHost,
},
MaxPendingChannels: defaultMaxPendingChannels,
NoSeedBackup: defaultNoSeedBackup,
Autopilot: &autoPilotConfig{
MaxChannels: 5,
Allocation: 0.6,
MinChannelSize: 0,
MaxChannelSize: 0,
},
TrickleDelay: defaultTrickleDelay,
InactiveChanTimeout: defaultInactiveChanTimeout,
Alias: defaultAlias,
Color: defaultColor,
MinChanSize: 0,
Tor: &torConfig{
SOCKS: defaultTorSOCKS,
DNS: defaultTorDNS,
Control: defaultTorControl,
},
net: &tor.ClearNet{},
} }
// Pre-parse the command line options to pick up an alternative config // Pre-parse the command line options to pick up an alternative config
@ -344,7 +131,12 @@ func loadConfig() (*config, error) {
// Next, load any additional configuration options from the file. // Next, load any additional configuration options from the file.
var configFileError error var configFileError error
cfg := preCfg cfg := preCfg
if err := flags.IniParse(cfg.ConfigFile, &cfg); err != nil {
// We don't have a full representation of all LND options in zapconnect
// so while parsing the config file, we only take what we need, ignoring
// all the unknown (to us) options.
p := flags.NewParser(&cfg, flags.IgnoreUnknown)
if err := flags.NewIniParser(p).ParseFile(cfg.ConfigFile); err != nil {
configFileError = err configFileError = err
} }
@ -412,24 +204,6 @@ func loadConfig() (*config, error) {
) )
} }
// At least one RPCListener is required. So listen on localhost per
// default.
if len(cfg.RawRPCListeners) == 0 {
addr := fmt.Sprintf("localhost:%d", defaultRPCPort)
cfg.RawRPCListeners = append(cfg.RawRPCListeners, addr)
}
var err error
// Add default port to all RPC listener addresses if needed and remove
// duplicate addresses.
cfg.RPCListeners, err = lncfg.NormalizeAddresses(
cfg.RawRPCListeners, strconv.Itoa(defaultRPCPort),
cfg.net.ResolveTCPAddr,
)
if err != nil {
return nil, err
}
// Warn about missing config file only after all other configuration is // Warn about missing config file only after all other configuration is
// done. This prevents the warning on help messages and invalid // done. This prevents the warning on help messages and invalid
// options. Note this should go directly before the return. // options. Note this should go directly before the return.
@ -452,9 +226,9 @@ func cleanAndExpandPath(path string) string {
if strings.HasPrefix(path, "~") { if strings.HasPrefix(path, "~") {
var homeDir string var homeDir string
user, err := user.Current() u, err := user.Current()
if err == nil { if err == nil {
homeDir = user.HomeDir homeDir = u.HomeDir
} else { } else {
homeDir = os.Getenv("HOME") homeDir = os.Getenv("HOME")
} }

54
zapconnect.go

@ -1,22 +1,23 @@
package main package main
import ( import (
b64 "encoding/base64"
"encoding/json"
"encoding/pem"
"fmt" "fmt"
"net"
"io/ioutil" "io/ioutil"
"github.com/Baozisoftware/qrcode-terminal-go" "net"
"encoding/json"
b64 "encoding/base64"
"os" "os"
"encoding/pem"
"github.com/glendc/go-external-ip" "github.com/Baozisoftware/qrcode-terminal-go"
qrcode "github.com/skip2/go-qrcode" "github.com/glendc/go-external-ip"
"github.com/skip2/go-qrcode"
) )
type certificates struct { type certificates struct {
Cert string `json:"c"` Cert string `json:"c"`
Macaroon string `json:"m"` Macaroon string `json:"m"`
Ip string `json:"ip,omitempty"` Ip string `json:"ip,omitempty"`
} }
func getLocalIP() string { func getLocalIP() string {
@ -36,11 +37,11 @@ func getLocalIP() string {
func getPublicIP() string { func getPublicIP() string {
consensus := externalip.DefaultConsensus(nil, nil) consensus := externalip.DefaultConsensus(nil, nil)
ip, err := consensus.ExternalIP() ip, err := consensus.ExternalIP()
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
os.Exit(1) os.Exit(1)
} }
return ip.String() return ip.String()
} }
@ -67,11 +68,11 @@ func main() {
var macBytes []byte var macBytes []byte
if loadedConfig.ZapConnect.Invoice { if loadedConfig.ZapConnect.Invoice {
macBytes, err = ioutil.ReadFile(loadedConfig.InvoiceMacPath) macBytes, err = ioutil.ReadFile(loadedConfig.InvoiceMacPath)
} else if loadedConfig.ZapConnect.Readonly { } else if loadedConfig.ZapConnect.Readonly {
macBytes, err = ioutil.ReadFile(loadedConfig.ReadMacPath) macBytes, err = ioutil.ReadFile(loadedConfig.ReadMacPath)
} else { } else {
macBytes, err = ioutil.ReadFile(loadedConfig.AdminMacPath) macBytes, err = ioutil.ReadFile(loadedConfig.AdminMacPath)
} }
if err != nil { if err != nil {
@ -82,7 +83,9 @@ func main() {
macaroonB64 := b64.StdEncoding.EncodeToString([]byte(macBytes)) macaroonB64 := b64.StdEncoding.EncodeToString([]byte(macBytes))
ipString := "" ipString := ""
if loadedConfig.ZapConnect.LocalIp { if loadedConfig.ZapConnect.Host != "" {
ipString = loadedConfig.ZapConnect.Host
} else if loadedConfig.ZapConnect.LocalIp {
ipString = getLocalIP() ipString = getLocalIP()
} else if loadedConfig.ZapConnect.Localhost { } else if loadedConfig.ZapConnect.Localhost {
ipString = "127.0.0.1" ipString = "127.0.0.1"
@ -90,22 +93,17 @@ func main() {
ipString = getPublicIP() ipString = getPublicIP()
} }
addr := loadedConfig.RPCListeners[0] ipString = net.JoinHostPort(
_, port, err := net.SplitHostPort(addr.String()) ipString, fmt.Sprint(loadedConfig.ZapConnect.Port),
if err != nil { )
fmt.Println(err)
return
}
ipString = net.JoinHostPort(ipString, port)
cert := &certificates{ cert := &certificates{
Cert: certificate, Cert: certificate,
Macaroon: macaroonB64, Macaroon: macaroonB64,
Ip: ipString} Ip: ipString,
}
certB, _ := json.Marshal(cert) certB, _ := json.Marshal(cert)
if loadedConfig.ZapConnect.Json { if loadedConfig.ZapConnect.Json {
fmt.Println(string(certB)) fmt.Println(string(certB))
} else if loadedConfig.ZapConnect.Image { } else if loadedConfig.ZapConnect.Image {

Loading…
Cancel
Save