diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..c23774c --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,17 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Launch", + "type": "go", + "request": "launch", + "mode": "auto", + "program": "${fileDirname}", + "env": {}, + "args": [] + } + ] +} \ No newline at end of file diff --git a/cyphernodeconf_docker/Dockerfile b/cyphernodeconf_docker/Dockerfile index e51c158..aefacdc 100644 --- a/cyphernodeconf_docker/Dockerfile +++ b/cyphernodeconf_docker/Dockerfile @@ -1,8 +1,24 @@ +FROM golang:1.13-alpine3.10 as builder + +RUN apk add git build-base + +RUN mkdir -p /go/src/torgen + +COPY torgen/torgen.go /go/src/torgen + +WORKDIR /go/src/torgen + +RUN go get + +RUN go build torgen.go +RUN chmod +x /go/src/torgen/torgen + FROM node:12.2.0-alpine ENV EDITOR=/usr/bin/nano COPY . /app +COPY --from=builder /go/src/torgen/torgen /app/torgen WORKDIR /app RUN mkdir /data && \ diff --git a/cyphernodeconf_docker/lib/app.js b/cyphernodeconf_docker/lib/app.js index c9cced2..fd9fe4c 100644 --- a/cyphernodeconf_docker/lib/app.js +++ b/cyphernodeconf_docker/lib/app.js @@ -22,6 +22,7 @@ const SplashScreen = require( './splashScreen.js' ); const ansi = require( './ansi.js' ); const features = require('../features.json'); +const torifyables = require('../torifyables.json'); const uaCommentRegexp = /^[a-zA-Z0-9 \.,:_\-\?\/@]+$/; // TODO: look for spec of unsafe chars const userRegexp = /^[a-zA-Z0-9\._\-]+$/; @@ -56,6 +57,7 @@ module.exports = class App { constructor() { this.features = features; + this.torifyables = torifyables; if( fs.existsSync(path.join('/data', destinationDirName, 'exitStatus.sh')) ) { fs.unlinkSync(path.join('/data', destinationDirName, 'exitStatus.sh')); @@ -224,6 +226,9 @@ module.exports = class App { feature.checked = this.isChecked( 'features', feature.value ); } + for( let torifyable of this.torifyables ) { + torifyable.checked = this.isChecked( 'torifyables', torifyable.value ); + } } async startWizard() { @@ -397,6 +402,10 @@ module.exports = class App { feature.checked = this.isChecked( 'features', feature.value ); } + for( let torifyable of this.torifyables ) { + torifyable.checked = this.isChecked( 'torifyables', torifyable.value ); + } + const cert = new Cert(); const gatekeeper_cns = cert.cns( this.config.data.gatekeeper_cns ); @@ -638,6 +647,10 @@ module.exports = class App { return this.features; } + torifyableChoices() { + return this.torifyables; + } + setupDir() { return this.sessionData.setupDir; } diff --git a/cyphernodeconf_docker/prompters/040_tor.js b/cyphernodeconf_docker/prompters/040_tor.js index 8a85198..198f440 100644 --- a/cyphernodeconf_docker/prompters/040_tor.js +++ b/cyphernodeconf_docker/prompters/040_tor.js @@ -10,15 +10,68 @@ const prefix = function() { return chalk.green(capitalise(name)+': '); }; +const featureCondition = function(props) { + return props.features && props.features.indexOf( name ) != -1; +}; + module.exports = { name: function() { return name; }, prompts: function( utils ) { - return [ - ]; + return [{ + // https://github.com/SBoudrias/Inquirer.js#question + // input, confirm, list, rawlist, expand, checkbox, password, editor + when: featureCondition, + type: 'checkbox', + name: 'torifyables', + message: prefix()+'What features do you want to TORify?'+utils.getHelp('torifyables'), + choices: utils.torifyableChoices() + }]; + }, + { + when: featureCondition, + type: 'checkbox', + name: 'clearnet', + default: utils.getDefault( 'clearnet' ), + message: prefix()+'What features do you want to allow using clearnet?'+utils.getHelp('clearnet'), + choices: [{ + name: "Bitcoin Node", + value: "clearnet_bitcoinnode" + },{ + name: "LN Node", + value: "clearnet_lnnode" + }] }, templates: function( props ) { return [ 'torrc' ]; } }; + +// Do you want to access Cyphernode via a TOR Hidden Service? +// Do you want to access Cyphernode also via clearnet? +// Do you want your Bitcoin node to use TOR? +// Do you want your Bitcoin node to also use clearnet? +// Do you want your LN node to use TOR? +// Do you want your LN node to also use clearnet? +// Do you want your OTS client to use TOR? +// Do you want your Cyphernode callbacks (address watches, TXID watches and OTS notifications) to perform through TOR? + +// Do you want TOR? +// What do you want to TOR? +// - Cyphernode as Hidden Service +// - Bitcoin Node +// - LN Node +// - OTS stamp, upgrade and verify +// - OTS Callbacks (webhooks) +// - Address Watches Callbacks (webhooks) +// - TXID Watches Callbacks (webhooks) + +Certain services can also use clearnet. What do you want to allow to use clearnet? +- Bitcoin Node +- LN Node + +Do you want to announce your LN node onion address and/or IP address? + +What is your public IP address? + diff --git a/cyphernodeconf_docker/prompters/100_lightning.js b/cyphernodeconf_docker/prompters/100_lightning.js index 97a5c1d..501b63f 100644 --- a/cyphernodeconf_docker/prompters/100_lightning.js +++ b/cyphernodeconf_docker/prompters/100_lightning.js @@ -60,7 +60,7 @@ module.exports = { default: utils.getDefault( 'lightning_external_ip' ), filter: utils.trimFilter, validate: utils.ipOrFQDNValidator, - message: prefix()+'What external ip does your lightning node have?'+utils.getHelp('lightning_external_ip'), + message: prefix()+'What external IP does your lightning node have?'+utils.getHelp('lightning_external_ip'), }, { when: featureCondition, diff --git a/cyphernodeconf_docker/schema/config-v0.2.3.json b/cyphernodeconf_docker/schema/config-v0.2.3.json index 55e18c2..16622a4 100644 --- a/cyphernodeconf_docker/schema/config-v0.2.3.json +++ b/cyphernodeconf_docker/schema/config-v0.2.3.json @@ -100,6 +100,8 @@ "then": { "required": [ "tor_datapath" + "torifyables", + "clearnet" ] } }, @@ -193,6 +195,56 @@ ] } }, + "torifyables": { + "$id": "#/properties/torifyables", + "type": "array", + "title": "The TORified features of this cyphernode", + "default": [], + "items": { + "$id": "#/properties/torifyables/items", + "type": "string", + "enum": [ + "tor_hiddenservice", + "tor_bitcoinnode", + "tor_lnnode", + "tor_otsoperations", + "tor_otswebhooks", + "tor_addrwatcheswebhooks", + "tor_txidwatcheswebhooks" + ], + "title": "The TORified feature", + "default": "", + "examples": [ + "tor_hiddenservice", + "tor_bitcoinnode", + "tor_lnnode", + "tor_otsoperations", + "tor_otswebhooks", + "tor_addrwatcheswebhooks", + "tor_txidwatcheswebhooks" + ] + } + }, + "clearnet": { + "$id": "#/properties/clearnet", + "type": "array", + "title": "The clearnet-allowed TORified features of this cyphernode", + "default": [], + "items": { + "$id": "#/properties/clearnet/items", + "type": "string", + "enum": [ + "clearnet_bitcoinnode", + "clearnet_lnnode" + ], + "title": "The clearnet-allowed TORified feature", + "default": "", + "examples": [ + "clearnet_bitcoinnode", + "clearnet_lnnode" + ] + } + }, "net": { "$id": "#/properties/net", "type": "string", diff --git a/cyphernodeconf_docker/templates/bitcoin/bitcoin.conf b/cyphernodeconf_docker/templates/bitcoin/bitcoin.conf index db3710e..0ea411a 100644 --- a/cyphernodeconf_docker/templates/bitcoin/bitcoin.conf +++ b/cyphernodeconf_docker/templates/bitcoin/bitcoin.conf @@ -15,10 +15,12 @@ txindex=1 zmqpubrawblock=tcp://0.0.0.0:18501 zmqpubrawtx=tcp://0.0.0.0:18502 -<% if ( features.indexOf('tor') !== -1 ) { %> +<% if ( features.indexOf('tor_bitcoinnode') !== -1 ) { %> #tor proxy=tor:9050 -#onlynet=onion +<% if ( features.indexOf('clearnet_bitcoinnode') == -1 ) { %> +onlynet=onion +<% } %> listen=1 <% } %> diff --git a/cyphernodeconf_docker/templates/installer/docker/docker-compose.yaml b/cyphernodeconf_docker/templates/installer/docker/docker-compose.yaml index e5977b9..7806399 100644 --- a/cyphernodeconf_docker/templates/installer/docker/docker-compose.yaml +++ b/cyphernodeconf_docker/templates/installer/docker/docker-compose.yaml @@ -2,6 +2,54 @@ version: "3" services: + <% if ( features.indexOf('tor') !== -1 ) { %> + ########################## + # TOR # + ########################## + + tor: + image: cyphernode/tor:<%= tor_version %> + # Sleeping 7 seconds to let lightning and traefik start + command: $USER sh -c 'sleep 7 ; export HOME=/tor ; tor -f /tor/torrc' + volumes: + - "<%= tor_datapath %>:/tor" + restart: always + networks: + - cyphernodenet + - cyphernodeappsnet +# deploy: +# placement: +# constraints: [node.hostname==dev] + <% } %> + + <% if ( features.indexOf('lightning') !== -1 && lightning_implementation === 'c-lightning' ) { %> + ########################## + # LIGHTNING # + ########################## + + lightning: + image: cyphernode/clightning:<%= lightning_version %> + command: $USER sh -c 'while [ ! -f "/bitcoin_monitor/up" ]; do echo "bitcoin not ready" ; sleep 10 ; done ; echo "bitcoin ready!" ; lightningd' + <% if( lightning_expose ) { %> + ports: + - "9735:9735" + <% } %> + volumes: + - "<%= lightning_datapath %>:/.lightning" + - "<%= bitcoin_datapath %>/bitcoin-client.conf:/.bitcoin/bitcoin.conf:ro" + - bitcoin_monitor:/bitcoin_monitor:ro + networks: + - cyphernodenet + restart: always + <% if ( features.indexOf('tor') !== -1 ) { %> + depends_on: + - tor + <% } %> +# deploy: +# placement: +# constraints: [node.hostname==dev] + <% } %> + <% if( bitcoin_mode === 'internal' ) { %> ########################## # BITCOIN # @@ -249,51 +297,6 @@ services: # placement: # constraints: [node.hostname==dev] - <% if ( features.indexOf('tor') !== -1 ) { %> - ########################## - # TOR # - ########################## - - tor: - image: cyphernode/tor:<%= tor_version %> - command: $USER sh -c 'export HOME=/tor && tor -f /tor/torrc' - volumes: - - "<%= tor_datapath %>:/tor" - restart: always - networks: - - cyphernodenet - - cyphernodeappsnet -# deploy: -# placement: -# constraints: [node.hostname==dev] - <% } %> - - <% if ( features.indexOf('lightning') !== -1 && lightning_implementation === 'c-lightning' ) { %> - ########################## - # LIGHTNING # - ########################## - - lightning: - image: cyphernode/clightning:<%= lightning_version %> - command: $USER sh -c 'while [ ! -f "/bitcoin_monitor/up" ]; do echo "bitcoin not ready" ; sleep 10 ; done ; echo "bitcoin ready!" ; lightningd' - <% if( lightning_expose ) { %> - ports: - - "9735:9735" - <% } %> - volumes: - - "<%= lightning_datapath %>:/.lightning" - - "<%= bitcoin_datapath %>/bitcoin-client.conf:/.bitcoin/bitcoin.conf:ro" - - bitcoin_monitor:/bitcoin_monitor:ro - networks: - - cyphernodenet - restart: always - depends_on: - - bitcoin -# deploy: -# placement: -# constraints: [node.hostname==dev] - <% } %> - volumes: bitcoin_monitor: diff --git a/cyphernodeconf_docker/templates/installer/start.sh b/cyphernodeconf_docker/templates/installer/start.sh index 8b50e21..297046f 100644 --- a/cyphernodeconf_docker/templates/installer/start.sh +++ b/cyphernodeconf_docker/templates/installer/start.sh @@ -56,7 +56,6 @@ fi export USER=$(id -u <%= default_username %>):$(id -g <%= default_username %>) <% } %> -export ARCH=$(uname -m) current_path="$(cd "$(dirname "$0")" >/dev/null && pwd)" <% if (docker_mode == 'swarm') { %> @@ -67,4 +66,11 @@ docker-compose -f $current_path/docker-compose.yaml up -d --remove-orphans start_apps +export ARCH=$(uname -m) +case "${ARCH}" in arm*) + printf "\r\n\033[1;31mSince we're on a slow RPi, let's give Docker 60 more seconds before performing our tests...\033[0m\r\n\r\n" + sleep 60 +;; +esac + . ./testdeployment.sh diff --git a/cyphernodeconf_docker/templates/installer/stop.sh b/cyphernodeconf_docker/templates/installer/stop.sh index 0141273..9ac13ab 100644 --- a/cyphernodeconf_docker/templates/installer/stop.sh +++ b/cyphernodeconf_docker/templates/installer/stop.sh @@ -49,12 +49,10 @@ stop_apps() { . ./.cyphernodeconf/installer/config.sh stop_apps -<% if (docker_mode == 'swarm') { %> export USER=$(id -u):$(id -g) -export ARCH=$(uname -m) + +<% if (docker_mode == 'swarm') { %> docker stack rm cyphernode <% } else if(docker_mode == 'compose') { %> -export USER=$(id -u):$(id -g) -export ARCH=$(uname -m) docker-compose -f $current_path/docker-compose.yaml down <% } %> diff --git a/cyphernodeconf_docker/templates/installer/testdeployment.sh b/cyphernodeconf_docker/templates/installer/testdeployment.sh index d08ea2e..1353721 100644 --- a/cyphernodeconf_docker/templates/installer/testdeployment.sh +++ b/cyphernodeconf_docker/templates/installer/testdeployment.sh @@ -49,16 +49,8 @@ fi export USER=$(id -u <%= default_username %>):$(id -g <%= default_username %>) <% } %> -export ARCH=$(uname -m) current_path="$(cd "$(dirname "$0")" >/dev/null && pwd)" -arch=$(uname -m) -case "${arch}" in arm*) - printf "\r\n\033[1;31mSince we're on a slow RPi, let's give Docker 60 more seconds before performing our tests...\033[0m\r\n\r\n" - sleep 60 -;; -esac - # Will test if Cyphernode is fully up and running... docker run --rm -it -v $current_path/testfeatures.sh:/testfeatures.sh \ -v <%= gatekeeper_datapath %>:/gatekeeper \ @@ -85,4 +77,8 @@ fi printf "\r\n\033[0;92mDepending on your current location and DNS settings, point your favorite browser to one of the following URLs to access Cyphernode's status page:\r\n" printf "\r\n" printf "\033[0;95m<% cns.forEach(cn => { %><%= ('https://' + cn + '/welcome\\r\\n') %><% }) %>\033[0m\r\n" +<% if ( features.indexOf('tor') !== -1 ) { %> +printf "\033[0;92mYou can also use TOR Browser and navigate to your onion address:\r\n" +printf "\033[0;95mhttps://${TOR_HOSTNAME}/welcome\033[0m\r\n\r\n" +<% } %> printf "\033[0;92mUse 'admin' as the username with the configuration password you selected at the beginning of the configuration process.\r\n\r\n\033[0m" diff --git a/cyphernodeconf_docker/templates/installer/testfeatures.sh b/cyphernodeconf_docker/templates/installer/testfeatures.sh index 82a9523..f17456e 100644 --- a/cyphernodeconf_docker/templates/installer/testfeatures.sh +++ b/cyphernodeconf_docker/templates/installer/testfeatures.sh @@ -440,3 +440,6 @@ result="{${result}]}" echo "${result}" > /gatekeeper/installation.json echo "EXIT_STATUS=${finalreturncode}" > /dist/exitStatus.sh +<% if (features.indexOf('tor') != -1) { %> +echo "TOR_HOSTNAME=$(cat /dist/cyphernode/tor/hidden_service/hostname)" >> /dist/exitStatus.sh +<% } %> diff --git a/cyphernodeconf_docker/templates/lightning/c-lightning/config b/cyphernodeconf_docker/templates/lightning/c-lightning/config index 501b731..e4df753 100644 --- a/cyphernodeconf_docker/templates/lightning/c-lightning/config +++ b/cyphernodeconf_docker/templates/lightning/c-lightning/config @@ -16,13 +16,23 @@ rgb=<%= lightning_nodecolor %> addr=0.0.0.0:9735 -<% if ( features.indexOf('tor') !== -1 ) { %> +<% if ( features.indexOf('tor_lnnode') !== -1 ) { %> #tor proxy=tor:9050 -#always-use-proxy=true +<% if ( features.indexOf('clearnet_lnnode') == -1 ) { %> +always-use-proxy=true +<% } %> #disable-dns <% } else { %> <% if( locals.lightning_external_ip ) { %> announce-addr=<%= locals.lightning_external_ip %>:9735 <% } %> <% } %> +<% if (lightning_announce) { %> + <% if ( features.indexOf('tor_lnnode') !== -1 ) { %> + announce-addr=<%= locals.lightning_external_ip %>:1234 + <% if ( features.indexOf('clearnet_lnnode') == -1 ) { %> + announce-addr=onionaddress:9735 + <% } %> + <% } %> +<% } %> diff --git a/cyphernodeconf_docker/templates/tor/torrc b/cyphernodeconf_docker/templates/tor/torrc index 77fa950..18a09eb 100644 --- a/cyphernodeconf_docker/templates/tor/torrc +++ b/cyphernodeconf_docker/templates/tor/torrc @@ -1,3 +1,4 @@ +<% if ( features.indexOf('tor_hiddenservice') !== -1 ) { %> HiddenServiceDir /tor/hidden_service/ HiddenServiceVersion 3 HiddenServicePort 80 traefik:80 @@ -5,5 +6,7 @@ HiddenServicePort 443 traefik:443 <% if ( features.indexOf('lightning') !== -1 ) { %> HiddenServicePort 1234 lightning:9735 <% } %> +<% } %> + SocksPort 0.0.0.0:9050 ExitPolicy reject *:* # no exits allowed diff --git a/cyphernodeconf_docker/torgen/torgen.go b/cyphernodeconf_docker/torgen/torgen.go new file mode 100644 index 0000000..8eab44a --- /dev/null +++ b/cyphernodeconf_docker/torgen/torgen.go @@ -0,0 +1,125 @@ +/* + * MIT License + * + * Copyright (c) 2019 kexkey + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILIT * Y, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package main + +import ( + "bytes" + "encoding/base32" + "fmt" + "os" + "path" + "strings" + + "crypto/ed25519" + "crypto/sha512" + + "golang.org/x/crypto/sha3" +) + +func main() { + + path := path.Clean(os.Args[1]) + fmt.Println("path=" + path) + + /** + About the key files format: https://gitweb.torproject.org/tor.git/tree/src/lib/crypt_ops/crypto_format.c?h=tor-0.4.1.6#n34 + + Write the datalen bytes from data to the file named + fname in the tagged-data format. This format contains a + 32-byte header, followed by the data itself. The header is the + NUL-padded string "== typestring: tag ==". The length + of typestring and tag must therefore be no more than + 24. + + About the secret key format: https://gitweb.torproject.org/tor.git/tree/src/lib/crypt_ops/crypto_ed25519.h?h=tor-0.4.1.6#n29 + + Note that we store secret keys in an expanded format that doesn't match + the format from standard ed25519. Ed25519 stores a 32-byte value k and + expands it into a 64-byte H(k), using the first 32 bytes for a multiplier + of the base point, and second 32 bytes as an input to a hash function + for deriving r. But because we implement key blinding, we need to store + keys in the 64-byte expanded form. + **/ + + // Key pair generation + fmt.Println("Generating ed25519 keys...") + publicKey, privateKey, _ := ed25519.GenerateKey(nil) + + // Convert seed to expanded private key... + // Ref.: https://gitweb.torproject.org/tor.git/tree/src/ext/ed25519/donna/ed25519_tor.c?h=tor-0.4.1.6#n61 + // Ref.: https://gitweb.torproject.org/tor.git/tree/src/ext/curve25519_donna/README?h=tor-0.4.1.6#n28 + fmt.Println("Converting keys for TOR...") + h := sha512.Sum512(privateKey[:32]) + h[0] &= 248 + h[31] &= 127 + h[31] |= 64 + + // Create the Tor Hidden Service private key file + fmt.Println("Creating secret file...") + var fileBytes bytes.Buffer + fileBytes.Write([]byte("== ed25519v1-secret: type0 ==")) + fileBytes.Write(bytes.Repeat([]byte{0x00}, 3)) + fileBytes.Write(h[:]) + + prvFile, _ := os.Create(path + "/hs_ed25519_secret_key") + fileBytes.WriteTo(prvFile) + prvFile.Close() + + // Create the Tor Hidden Service public key file + fmt.Println("Creating public file...") + fileBytes.Reset() + fileBytes.Write([]byte("== ed25519v1-public: type0 ==")) + fileBytes.Write(bytes.Repeat([]byte{0x00}, 3)) + fileBytes.Write([]byte(publicKey)) + + pubFile, _ := os.Create(path + "/hs_ed25519_public_key") + fileBytes.WriteTo(pubFile) + pubFile.Close() + + // From https://github.com/rdkr/oniongen-go + // checksum = H(".onion checksum" || pubkey || version) + fmt.Println("Creating onion address...") + var checksumBytes bytes.Buffer + checksumBytes.Write([]byte(".onion checksum")) + checksumBytes.Write([]byte(publicKey)) + checksumBytes.Write([]byte{0x03}) + checksum := sha3.Sum256(checksumBytes.Bytes()) + + // onion_address = base32(pubkey || checksum || version) + var onionAddressBytes bytes.Buffer + onionAddressBytes.Write([]byte(publicKey)) + onionAddressBytes.Write([]byte(checksum[:2])) + onionAddressBytes.Write([]byte{0x03}) + onionAddress := base32.StdEncoding.EncodeToString(onionAddressBytes.Bytes()) + + // Create the Tor Hidden Service hostname file + fmt.Println("Creating onion address file...") + nameFile, _ := os.Create(path + "/hostname") + nameFile.WriteString(strings.ToLower(onionAddress) + ".onion\n") + nameFile.Close() + + fmt.Println("Done!") + +} diff --git a/cyphernodeconf_docker/torifyables.json b/cyphernodeconf_docker/torifyables.json new file mode 100644 index 0000000..93da55d --- /dev/null +++ b/cyphernodeconf_docker/torifyables.json @@ -0,0 +1,30 @@ +[ + { + "name": "Cyphernode as Hidden Service", + "value": "tor_hiddenservice" + }, + { + "name": "Bitcoin Node", + "value": "tor_bitcoinnode" + }, + { + "name": "LN Node", + "value": "tor_lnnode" + }, + { + "name": "OTS stamp, upgrade and verify", + "value": "tor_otsoperations" + }, + { + "name": "OTS Callbacks (webhooks)", + "value": "tor_otswebhooks" + }, + { + "name": "Address Watches Callbacks (webhooks)", + "value": "tor_addrwatcheswebhooks" + }, + { + "name": "TXID Watches Callbacks (webhooks)", + "value": "tor_txidwatcheswebhooks" + } +] diff --git a/dist/setup.sh b/dist/setup.sh index 9297d32..680c91e 100755 --- a/dist/setup.sh +++ b/dist/setup.sh @@ -721,6 +721,22 @@ install() { fi } +manage_tor_keys() { + until [ -f hostname ] && [ -f hs_ed25519_secret_key ] && [ -f hs_ed25519_public_key ] +do + sleep 0.1 + max=$(($max-1)) + if [[ $max == 0 ]] + then + # Kill Tor on timeout and exit with error code 1. + kill -9 $pid >/dev/null 2>&1 + rm -f torrc hostname hs_ed25519_secret_key hs_ed25519_public_key + popd >/dev/null 2>&1 + exit 1 + fi +done +} + CONFIGURE=0 INSTALL=0 RECREATE=0 @@ -813,6 +829,9 @@ if [[ $CONFIGURE == 1 ]]; then configure $RECREATE fi +# If TOR is installed, we want to create the Hidden Serivce hostname now to make it +# available to LN and whatever needs it at this point... +manage_tor_keys if [[ -f "$cyphernodeconf_filepath/installer/config.sh" ]]; then . "$cyphernodeconf_filepath/installer/config.sh"