diff --git a/home.admin/config.scripts/blitz.mnemonic.py b/home.admin/config.scripts/blitz.mnemonic.py new file mode 100755 index 000000000..cad4d7633 --- /dev/null +++ b/home.admin/config.scripts/blitz.mnemonic.py @@ -0,0 +1,20 @@ +#!/usr/bin/python3 + +from mnemonic import Mnemonic + +mnemo = Mnemonic("english") +seedwords = mnemo.generate(strength=256) + +print("seedwords='" + seedwords + "'") + +# add a 6x4 formatted version to the output +wordlist = list(seedwords.split(" ")) +seed_words_6x4 = "" +for i in range(0, len(wordlist)): + if i % 6 == 0 and i != 0: + seed_words_6x4 = seed_words_6x4 + "\n" + single_word = str(i + 1) + ":" + wordlist[i] + while len(single_word) < 12: + single_word = single_word + " " + seed_words_6x4 = seed_words_6x4 + single_word +print("seedwords6x4='" + seed_words_6x4 + "'") \ No newline at end of file diff --git a/home.admin/config.scripts/cln.backup.sh b/home.admin/config.scripts/cln.backup.sh new file mode 100755 index 000000000..8ae9e46d2 --- /dev/null +++ b/home.admin/config.scripts/cln.backup.sh @@ -0,0 +1,137 @@ +#!/bin/bash + +# command info +if [ $# -eq 0 ] || [ "$1" = "-h" ] || [ "$1" = "-help" ]; then + echo "# ---------------------------------------------------" + + echo "# SEED WORDS" + echo "# ---------------------------------------------------" + echo "# cln.backup.sh seed-export-gui [lndseeddata]" + echo "# cln.backup.sh seed-import-gui [resultfile]" + exit 1 +fi + +# 1st PARAMETER action +mode="$1" + + +#################################### +# SEED WORDS - GUI PARTS +#################################### + +if [ ${mode} = "seed-export-gui" ]; then + + # use text snippet for testing: + # + + # 2nd PARAMETER: lnd seed data + seedwords6x4=$2 + if [ "${seedwords6x4}" == "" ]; then + echo "error='missing parameter'" + exit 1 + fi + + ack=0 + while [ ${ack} -eq 0 ] + do + whiptail --title "IMPORTANT SEED WORDS - PLEASE WRITE DOWN" --msgbox "C-Lightning Wallet got created. Store these numbered words in a safe location:\n\n${seedwords6x4}" 12 76 + whiptail --title "Please Confirm" --yes-button "Show Again" --no-button "CONTINUE" --yesno " Are you sure that you wrote down the word list?" 8 55 + if [ $? -eq 1 ]; then + ack=1 + fi + done + +fi + +# Results will be stored on memory cache: +# /var/cache/raspiblitz/seed-import.results +if [ ${mode} = "seed-import-gui" ]; then + + # fake seed 24 words for testing input: + # eins zwei polizei drei vier great idea fünf sechs alte keks sieben auch gute nacht ja ja ja was ist los was ist das + + # scenario setup needs a 3rd parameter - the RESULTFILE to store results in + RESULTFILE=$2 + if [ "${RESULTFILE}" == "" ]; then + echo "error='missing parameter'" + exit 1 + fi + + # prepare seed result file + sudo rm /var/cache/raspiblitz/seed-import.results 2>/dev/null + sudo touch /var/cache/raspiblitz/seed-import.results + sudo chown admin:admin /var/cache/raspiblitz/seed-import.results + + # input loop for seed words + wordsCorrect=0 + while [ ${wordsCorrect} -eq 0 ] + do + + # prepare temp file + sudo rm /var/cache/raspiblitz/.seed.tmp 2>/dev/null + sudo touch /var/cache/raspiblitz/.seed.tmp + sudo chown admin:admin /var/cache/raspiblitz/.seed.tmp + + # dialog to enter + dialog --backtitle "RaspiBlitz - C-lightning Recover" --inputbox "Please enter/paste the SEED WORD LIST:\n(just the words, seperated by spaces, in correct order as numbered)" 9 78 2>/var/cache/raspiblitz/.seed.tmp + wordstring=$(cat /var/cache/raspiblitz/.seed.tmp | sed 's/[^a-zA-Z0-9 ]//g') + sudo shred -u /var/cache/raspiblitz/.seed.tmp 2>/dev/null + echo "processing ..." + + # check correct number of words + wordcount=$(echo "${wordstring}" | wc -w) + if [ ${wordcount} -eq 24 ]; then + echo "OK - 24 words" + wordsCorrect=1 + else + whiptail --title " WARNING " \ + --yes-button "Try Again" \ + --no-button "Cancel" \ + --yesno " +The word list has ${wordcount} words. But it must be 24. +Please check your list and try again. + +Best is to write words in external editor +and then copy and paste them into dialog. + +The Word list should look like this: +wordone wordtweo wordthree ... + +" 16 52 + + if [ $? -eq 1 ]; then + clear + echo "# CANCEL empty results in: ${RESULTFILE}" + exit 1 + fi + fi + done + + # ask if seed was protected by password D + passwordD="" + dialog --title "SEED PASSWORD" --yes-button "No extra Password" --no-button "Yes" --yesno " +Are your seed words protected by an extra password? + +During wallet creation LND offers to set an extra password +to protect the seed words. Most users did not set this. + " 11 65 + if [ $? -eq 1 ]; then + sudo rm /var/cache/raspiblitz/.pass.tmp 2>/dev/null + sudo touch /var/cache/raspiblitz/.pass.tmp + sudo chown admin:admin /var/cache/raspiblitz/.pass.tmp + sudo /home/admin/config.scripts/blitz.setpassword.sh x "Enter extra Password D" /var/cache/raspiblitz/.pass.tmp empty-allowed + passwordD=$(sudo cat /var/cache/raspiblitz/.pass.tmp) + sudo shred -u /var/cache/raspiblitz/.pass.tmp 2>/dev/null + fi + + # writing result file data + clear + echo "# result in: ${RESULTFILE} (remember to make clean delete once processed)" + echo "seedWords='${wordstring}'" >> $RESULTFILE + echo "seedPassword='${passwordD}'" >> $RESULTFILE + exit 0 + +fi + +echo "error='unknown parameter'" +exit 1 diff --git a/home.admin/config.scripts/cln.hsmtool.sh b/home.admin/config.scripts/cln.hsmtool.sh index 354e15044..284911229 100644 --- a/home.admin/config.scripts/cln.hsmtool.sh +++ b/home.admin/config.scripts/cln.hsmtool.sh @@ -1,27 +1,39 @@ #!/bin/bash # keeps the password in memory between restarts: /dev/shm/.${netprefix}cln.pw +# see the reasoning: https://github.com/ElementsProject/lightning#hd-wallet-encryption # does not store the password on disk unless auto-unlock is enabled # autounlock password is in /root/.${netprefix}cln.pw # command info if [ $# -lt 1 ] || [ "$1" = "-h" ] || [ "$1" = "-help" ]||\ - ! echo "$@" | grep -Eq "unlock|lock|encrypt|decrypt|autounlock-on|autounlock-off|change-password" ;then + ! echo "$@" | grep -Eq "new|seed|unlock|lock|encrypt|decrypt|autounlock-on|autounlock-off|change-password" ;then echo + echo "# create new wallet or import seed" echo "# unlock/lock, encrypt, decrypt, set autounlock or change password for the hsm_secret" echo echo "# usage:" - echo "# cln.hsmtool.sh [unlock|lock] [testnet|mainnet|signet]" - echo "# cln.hsmtool.sh [encrypt|decrypt] [testnet|mainnet|signet]" - echo "# cln.hsmtool.sh [autounlock-on|autounlock-off] [testnet|mainnet|signet]" - echo "# cln.hsmtool.sh [change-password] [testnet|mainnet|signet]" + echo "# Create new wallet" + echo "# cln.hsmtool.sh [new] [mainnet|testnet|signet] [?seedPassword]" + echo "# There will be no seedPassword(passphrase) used by default" + echo + echo "# cln.hsmtool.sh [seed] [mainnet|testnet|signet] [\"space-separated-seed-words\"] [?seedPassword]" + echo "# the new hsm_secret will be not encrypted if no NewPassword is given" + echo + echo "# cln.hsmtool.sh [unlock|lock] " + echo "# cln.hsmtool.sh [encrypt|decrypt] " + echo "# cln.hsmtool.sh [autounlock-on|autounlock-off] " + echo + echo "# cln.hsmtool.sh [change-password] " echo exit 1 fi source /mnt/hdd/raspiblitz.conf source <(/home/admin/config.scripts/network.aliases.sh getvars cln $2) +hsmSecretPath="/home/bitcoin/.lightning/${CLNETWORK}/hsm_secret" +# password file is on the disk if encrypted and auto-unlock is enabled passwordFile=/dev/shm/.${netprefix}cln.pw if grep -Eq "${netprefix}clnEncryptedHSM=on" /mnt/hdd/raspiblitz.conf;then if grep -Eq "${netprefix}clnAutoUnlock=on" /mnt/hdd/raspiblitz.conf;then @@ -47,7 +59,7 @@ function passwordToFile() { else text="Type or paste the decryption password for the $CHAIN C-lightning wallet" fi - # write password into a file (to be shredded) + # write password into a file in memory # get password data=$(mktemp -p /dev/shm/) # trap it @@ -87,14 +99,18 @@ function shredPasswordFile() { } function encryptHSMsecret() { - sudo /home/admin/config.scripts/blitz.setpassword.sh x \ - "Enter the password to encrypt the C-lightning wallet file (hsm_secret)" \ - "$passwordFile" - sudo chmod 600 $passwordFile - sudo chown bitcoin:bitcoin $passwordFile - (sudo cat $passwordFile;sudo cat $passwordFile) | sudo -u bitcoin \ + walletPassword=$3 + if [ ${#walletPassword} -eq 0 ];then + # ask for password in dialog if $walletPassword is not given in $3 + sudo /home/admin/config.scripts/blitz.setpassword.sh x \ + "Enter the password to encrypt the C-lightning wallet file (hsm_secret)" \ + "$passwordFile" + sudo chmod 600 $passwordFile + walletPassword=$(sudo cat $passwordFile) + fi + (echo $walletPassword; echo $walletPassword) | sudo -u bitcoin \ /home/bitcoin/lightning/tools/hsmtool encrypt \ - /home/bitcoin/.lightning/${CLNETWORK}/hsm_secret || exit 1 + $hsmSecretPath || exit 1 # setting value in raspiblitz config sudo sed -i \ "s/^${netprefix}clnEncryptedHSM=.*/${netprefix}clnEncryptedHSM=on/g" \ @@ -110,7 +126,7 @@ function decryptHSMsecret() { fi sudo cat $passwordFile | sudo -u bitcoin \ /home/bitcoin/lightning/tools/hsmtool decrypt \ - /home/bitcoin/.lightning/${CLNETWORK}/hsm_secret || exit 1 + $hsmSecretPath || exit 1 shredPasswordFile # setting value in raspiblitz config sudo sed -i \ @@ -122,7 +138,42 @@ function decryptHSMsecret() { ########### # Options # ########### -if [ "$1" = "unlock" ]; then +if [ "$1" = "new" ] || [ "$1" = "seed" ]; then + if ! sudo ls $hsmSecretPath 2>1 1>/dev/null; then + + # check for https://github.com/trezor/python-mnemonic + if [ $(pip list | grep -c mnemonic) -eq 0 ];then + pip install mnemonic==0.19 + fi + if [ "$1" = "new" ]; then + seedPassword="$3" + # get 24 words + source <(python /home/admin/config.scripts/blitz.mnemonic.py) + #TODO seedWords to cln.backup.sh seed-export-gui + /home/admin/config.scripts/cln.backup.sh seed-export-gui $seedWords6x4 + elif [ "$1" = "seed" ]; then + #TODO get seedWords from cln.backup.sh seed-import-gui [$RESULTFILE] + seedWords="$3" + seedPassword="$4" + fi + # pass to 'hsmtool generatehsm hsm_secret' + if [ ${#seedPassword} -eq 0 ]; then + (echo "0"; echo "$seedWords"; echo) | \ + sudo -u bitcoin /home/bitcoin/lightning/tools/hsmtool "generatehsm" \ + $hsmSecretPath + else + # pass to 'hsmtool generatehsm hsm_secret' - confirm seedPassword + (echo "0";echo "$seedWords";echo "$seedPassword";echo "$seedPassword")|\ + sudo -u bitcoin /home/bitcoin/lightning/tools/hsmtool "generatehsm" \ + $hsmSecretPath + fi + exit 0 + else + echo "# The hsm_secret is already present at $hsmSecretPath." + exit 0 + fi + +elif [ "$1" = "unlock" ]; then # getpassword if [ $(sudo journalctl -n5 -u ${netprefix}lightningd | \ grep -c 'encrypted-hsm: Could not read pass from stdin.') -gt 0 ];then @@ -173,7 +224,8 @@ elif [ "$1" = "lock" ]; then exit 0 elif [ "$1" = "encrypt" ]; then - encryptHSMsecret + walletPassword=$3 + encryptHSMsecret $walletPassword elif [ "$1" = "decrypt" ]; then decryptHSMsecret @@ -202,7 +254,8 @@ elif [ "$1" = "autounlock-off" ]; then elif [ "$1" = "change-password" ]; then decryptHSMsecret || exit 1 - if ! encryptHSMsecret;then + walletPassword=$3 + if ! encryptHSMsecret "$walletPassword"; then echo "# Warning: the hsm_secret is left unencrypted." echo "# To fix run:" echo "/home/admin/config.scripts/cln.hsmtool encrypt $2" @@ -210,6 +263,15 @@ elif [ "$1" = "change-password" ]; then fi exit 0 +elif [ "$1" = "check" ]; then + # TODO + # dumponchaindescriptors [network] + # get current descriptors + sudo -u bitcoin /home/bitcoin/lightning/tools/hsmtool dumponchaindescriptors \ + /home/bitcoin/.lightning/${CLNETWORK}/hsm_secret $CLNETWORK + # get seed to compare + + else echo "# Unknown option - exiting script" exit 1