Compare commits
No commits in common. "master" and "master" have entirely different histories.
|
@ -1,6 +0,0 @@
|
|||
.env
|
||||
*.pyc
|
||||
tmp/
|
||||
_images/
|
||||
DICE
|
||||
♥Box
|
436
G1BILLETS.sh
|
@ -1,398 +1,60 @@
|
|||
#!/bin/bash
|
||||
################################################################################
|
||||
# Author: Fred (support@qo-op.com)
|
||||
# Version: 1.0
|
||||
# Version: 0.1
|
||||
# License: AGPL-3.0 (https://choosealicense.com/licenses/agpl-3.0/)
|
||||
################################################################################
|
||||
MY_PATH="`dirname \"$0\"`" # relative
|
||||
MY_PATH="`( cd \"$MY_PATH\" && pwd )`" # absolutized and normalized
|
||||
ME="${0##*/}"
|
||||
|
||||
## LOAD PERSONAL OR DEFAULT STYLES
|
||||
[[ -d ${MY_PATH}/_images/_/ ]] \
|
||||
&& IMAGES="_images" \
|
||||
|| IMAGES="images"
|
||||
|
||||
################################################################################
|
||||
# Create different king of G1BILLET(s) with $MONTANT DU or TW IPNS + ZENCARD
|
||||
# ${MY_PATH}/G1BILLETS.sh 5 ticket 2 # MONTANT # STYLE # SECURITE
|
||||
# Create and print 6 G1Billets de $MONTANT DU
|
||||
# ${MY_PATH}/G1BILLETS.sh 5 986397643
|
||||
################################################################################
|
||||
MONTANT="$1"
|
||||
|
||||
### COMMAND LINE MODE (DAEMON IS CALLING ITSELF) ###
|
||||
if [[ $MONTANT != "daemon" ]]; then
|
||||
|
||||
pidportinuse=$(lsof -i :33102 | tail -n 1 | awk '{print $2}')
|
||||
[[ $pidportinuse ]] && kill $pidportinuse && echo "KILLING NOT COLLECTED THREAD $pidportinuse"
|
||||
|
||||
[[ $MONTANT == "" || $MONTANT == "0" ]] && MONTANT="___"
|
||||
|
||||
STYLE="$2"
|
||||
|
||||
DICE="$3"
|
||||
|
||||
SECRET1="$4"
|
||||
SECRET2="$5"
|
||||
|
||||
[[ $DICE != ?(-)+([0-9]) ]] && DICE=$(cat $MY_PATH/DICE 2>/dev/null) ## HOW MANY WORDS SECRETS
|
||||
[[ $DICE != ?(-)+([0-9]) ]] && DICE=4
|
||||
|
||||
echo "G1BILLET FACTORY MONTANT=$MONTANT DICE=$DICE"
|
||||
echo "$STYLE : $MY_PATH/${IMAGES}/$STYLE"
|
||||
|
||||
## CHECK IF STYLE IS EMAIL => ZENCARD+@ IPFS G1BILLET
|
||||
if [[ "${STYLE}" =~ ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$ ]]; then
|
||||
|
||||
echo "ASTROPORT $STYLE :: ZENCARD+@"
|
||||
# echo "PLAYER : $STYLE"
|
||||
EMAIL=${STYLE}
|
||||
DICE=5
|
||||
|
||||
## DEFAULT xZSTYLE
|
||||
LASTX=$(ls -d ${MY_PATH}/${IMAGES}/x* | tail -n 1)
|
||||
STYLE="$(echo ${LASTX} | rev | cut -d '/' -f 1 | rev)"
|
||||
|
||||
fi
|
||||
|
||||
## STYLE SELECTED: PDF DE 6 BILLETS OR SINGLE
|
||||
[[ "${STYLE:0:1}" != "_" ]] && NBbillets=1 && MONTANT="___" ## NOT DEFAULT (empty or _ style)
|
||||
[[ ${STYLE} == "" || ${STYLE} == "_" ]] && NBbillets=6 && STYLE="_" # 6 x G1BILLET v1 = "MLC"
|
||||
|
||||
echo "G1BILLET MAKE $NBbillets - ${STYLE} (${DICE}) - "
|
||||
|
||||
# CHECK IF $STYLE IMAGES EXIST
|
||||
IMAGESSTYLE="${IMAGES}/${STYLE}"
|
||||
[[ ${STYLE} == "UPlanet" ]] && STYLE="xastro" ## DEFAULT : UPlanet Style
|
||||
[[ ! -f ${MY_PATH}/${IMAGES}/${STYLE}/g1.png ]] && ERROR="MISSING ./${IMAGES}/${STYLE}/g1.png - EXIT" && echo $ERROR && exit 1
|
||||
[[ ! -f ${MY_PATH}/${IMAGES}/${STYLE}/fond.jpg ]] && ERROR="MISSING ./${IMAGES}/${STYLE}/fond.jpg- EXIT" && echo $ERROR && exit 1
|
||||
[[ ! -f ${MY_PATH}/${IMAGES}/${STYLE}/logo.png ]] && ERROR="MISSING ./${IMAGES}/${STYLE}/logo.png- EXIT" && echo $ERROR && exit 1
|
||||
|
||||
# CREATION DE $NBbillets BILLETS DE $MONTANT DU
|
||||
boucle=0;
|
||||
while [ $boucle -lt $NBbillets ]
|
||||
do
|
||||
## THIS IS THE PASS for ZENCARD
|
||||
if [[ ${boucle} == 0 ]]; then
|
||||
UNIQID=$(echo "${RANDOM}${RANDOM}${RANDOM}${RANDOM}" | tail -c-5)
|
||||
[ $DICE -gt 4 ] && UNIQID=$(echo "${RANDOM}${RANDOM}${RANDOM}${RANDOM}" | tail -c-7)
|
||||
[ $DICE -gt 6 ] && UNIQID=$(${MY_PATH}/diceware.sh 1 | xargs)$(echo "${RANDOM}${RANDOM}" | tail -c-7)
|
||||
mkdir -p "${MY_PATH}/tmp/g1billet/${UNIQID}"
|
||||
fi
|
||||
boucle=$((boucle+1))
|
||||
|
||||
## ADAPT SECURITY LEVEL
|
||||
[[ ${SECRET1} == "" || $boucle -gt 1 ]] && SECRET1="${UNIQID} $(${MY_PATH}/diceware.sh $DICE | xargs)"
|
||||
[[ ${SECRET2} == "" || $boucle -gt 1 ]] && SECRET2=$(${MY_PATH}/diceware.sh $DICE | xargs)
|
||||
echo "${SECRET1}" "${SECRET2}"
|
||||
# CREATION CLEF BILLET
|
||||
BILLETPUBKEY=$(python3 ${MY_PATH}/key_create_dunikey.py "${SECRET1}" "${SECRET2}")
|
||||
rm -f /tmp/secret.dunikey
|
||||
echo "$boucle : $BILLETPUBKEY "
|
||||
|
||||
if [[ $DICE -ge 4 || "${STYLE:0:1}" != "_" ]]; then
|
||||
# + ASTRONS ## G1BILLET APP STICKER
|
||||
ASTRONS=$(${MY_PATH}/keygen -t ipfs "${SECRET1}" "${SECRET2}")
|
||||
echo "/ipns/$ASTRONS" # 12D3Koo style - QRCODE ipfs2g1 verify
|
||||
fi
|
||||
#######################################################################################################
|
||||
# CREATION FICHIER IMAGE BILLET dans ${MY_PATH}/tmp/g1billet/${UNIQID}
|
||||
#######################################################################################################
|
||||
echo ${MY_PATH}/MAKE_G1BILLET.sh '"'${SECRET1}'"' '"'${SECRET2}'"' "${MONTANT}" "${BILLETPUBKEY}" "${UNIQID}" "${STYLE}" "${ASTRONS}" "${EMAIL}"
|
||||
${MY_PATH}/MAKE_G1BILLET.sh "${SECRET1}" "${SECRET2}" "${MONTANT}" "${BILLETPUBKEY}" "${UNIQID}" "${STYLE}" "${ASTRONS}" "${EMAIL}"
|
||||
#######################################################################################################
|
||||
#######################################################################################################
|
||||
|
||||
done
|
||||
|
||||
if [[ ${NBbillets} == 1 ]]; then
|
||||
|
||||
# ONE FILE ONLY
|
||||
cp ${MY_PATH}/tmp/g1billet/${UNIQID}/*.jpg ${MY_PATH}/tmp/g1billet/${UNIQID}.jpg
|
||||
|
||||
# CLEANING TEMP FILES
|
||||
echo rm -Rf ${MY_PATH}/tmp/g1billet/${UNIQID}
|
||||
|
||||
# ALLOWS ANY USER TO DELETE
|
||||
chmod 777 ${MY_PATH}/tmp/g1billet/${UNIQID}.jpg
|
||||
export ZFILE="${MY_PATH}/tmp/g1billet/${UNIQID}.jpg"
|
||||
|
||||
else
|
||||
|
||||
# MONTAGE DES IMAGES DES BILLETS VERS ${MY_PATH}/tmp/g1billet/${UNIQID}.pdf
|
||||
montage ${MY_PATH}/tmp/g1billet/${UNIQID}/*.jpg -tile 2x3 -geometry 964x459 ${MY_PATH}/tmp/g1billet/${UNIQID}.pdf
|
||||
# NB!! if "not autorized" then edit /etc/ImageMagick-6/policy.xml and comment
|
||||
[[ ! -s ${MY_PATH}/tmp/g1billet/${UNIQID}.pdf ]] && echo "ERROR PDF NOT FOUND - contact - support@qo-op.com" && exit 1
|
||||
# <!-- <policy domain="coder" rights="none" pattern="PDF" /> -->
|
||||
|
||||
# CLEANING TEMP FILES
|
||||
rm -Rf ${MY_PATH}/tmp/g1billet/${UNIQID}
|
||||
|
||||
# ALLOWS ANY USER TO DELETE
|
||||
chmod 777 ${MY_PATH}/tmp/g1billet/${UNIQID}.pdf
|
||||
export ZFILE="${MY_PATH}/tmp/g1billet/${UNIQID}.pdf"
|
||||
|
||||
fi
|
||||
|
||||
###########################################################################
|
||||
[[ $XDG_SESSION_TYPE == 'x11' ]] && xdg-open "$ZFILE"
|
||||
###########################################################################
|
||||
echo "$ZFILE" # IMPORTANT ## LAST LINE : INFORM DAEMON
|
||||
###########################################################################
|
||||
|
||||
else
|
||||
################################################################################
|
||||
################################################################################
|
||||
## MAKE IT A NETWORK MICRO SERVICE -- PORTS : INPUT=33101 OUTPUT=33102
|
||||
############## CLEAN START DAEMON MODE ###
|
||||
pidportinuse=$(lsof -i :33101 | tail -n 1 | awk '{print $2}')
|
||||
[[ $pidportinuse ]] && echo "KILLING OLD DEAMON 33101 $pidportinuse" && kill -9 $pidportinuse && killall G1BILLETS.sh && exit 1
|
||||
|
||||
pidportinuse=$(lsof -i :33102 | head -n 1 | awk '{print $2}')
|
||||
[[ $pidportinuse ]] && kill $pidportinuse && echo "KILLING NOT COLLECTED THREAD $pidportinuse"
|
||||
#####################################################################
|
||||
myIP=$(hostname -I | awk '{print $1}' | head -n 1)
|
||||
isLAN=$(route -n |awk '$1 == "0.0.0.0" {print $2}' | grep -E "/(^127\.)|(^192\.168\.)|(^10\.)|(^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.)|(^::1$)|(^[fF][cCdD])/")
|
||||
isBOX=$(cat ${MY_PATH}/♥Box)
|
||||
|
||||
## WHERE DO CLIENT WILL GET FILE
|
||||
if [[ $isLAN ]]; then
|
||||
HNAME="http://g1billet.localhost"
|
||||
else
|
||||
HNAME="http://$(hostname -I | awk '{print $1}' | head -n 1)"
|
||||
fi
|
||||
RNAME="$HNAME:33102"
|
||||
[[ $isBOX != "" ]] && RNAME="$isBOX"
|
||||
|
||||
## AVAILABLE STYLES : CREATING SELECT
|
||||
sytle=($(find ${MY_PATH}/${IMAGES}/* -type d | sort | rev | cut -d '/' -f 1 | rev))
|
||||
sytlenb=${#sytle[@]}
|
||||
OPT=""
|
||||
for stname in ${sytle[@]}; do
|
||||
|
||||
pre=${stname:0:1}
|
||||
|
||||
if [[ $pre == "_" ]]; then
|
||||
OPT="${OPT}<option value='_'>:: G1BILLET :: (+) ::</option>"
|
||||
elif [[ $pre == "x" ]]; then
|
||||
OPT="${OPT}<option value='${stname}'>:: ZENCARD+TW :: ${stname} ::</option>"
|
||||
elif [[ $(echo ${stname} | grep '@') && -s ~/.zen/Astroport.ONE/tools/VOEUX.print.sh ]]; then
|
||||
OPT="${OPT}<option value='${stname}'>:: ZENCARD+@ :: ${stname} ::</option>"
|
||||
else
|
||||
OPT="${OPT}<option value='${stname}'>:: ZENCARD :: ${stname} ::</option>"
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
## WELCOME HTTP / HTML PAGE
|
||||
HTTPWELLCOME='HTTP/1.1 200 OK
|
||||
Access-Control-Allow-Origin: *
|
||||
Access-Control-Allow-Credentials: true
|
||||
Access-Control-Allow-Methods: GET
|
||||
Server: Astroport
|
||||
Content-Type: text/html; charset=UTF-8
|
||||
|
||||
<!DOCTYPE html><html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>[G1BILLET] HTTP MICRO SERVICE - 33101 - 33102 -</title>
|
||||
<meta http-equiv="refresh" content="30; url='$RNAME'" />
|
||||
<style>
|
||||
#countdown { display: flex; justify-content: center; align-items: center; color: #0e2c4c; font-size: 20px; width: 60px; height: 60px; background-color: #e7d9fc; border-radius: 50%;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<center><h1><a href="'$RNAME'">(♥‿‿♥)</a>.</h1></center>
|
||||
<center><div id="countdown"></div></center>
|
||||
<script>
|
||||
var timeLeft = 30;
|
||||
var elem = document.getElementById("countdown");
|
||||
var timerId = setInterval(countdown, 1000);
|
||||
|
||||
function countdown() {
|
||||
if (timeLeft == -1) {
|
||||
clearTimeout(timerId);
|
||||
doSomething();
|
||||
} else {
|
||||
elem.innerHTML = timeLeft + " s";
|
||||
timeLeft--;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<center>
|
||||
<form method="get">
|
||||
<br>
|
||||
|
||||
<label for="montant">Montant :</label>
|
||||
<select name="montant">
|
||||
<option value="0">_</option>
|
||||
<option value="1">1</option>
|
||||
<option value="2">2</option>
|
||||
<option value="5">5</option>
|
||||
<option value="10">10</option>
|
||||
<option value="20">20</option>
|
||||
<option value="50">50</option>
|
||||
<option value="100">100</option>
|
||||
</select>
|
||||
|
||||
<label for="type">Type :</label>
|
||||
<select name="type">
|
||||
<option value=''></option>
|
||||
'${OPT}'
|
||||
</select>
|
||||
|
||||
<label for="dice">Dice :</label>
|
||||
<select name="dice">
|
||||
<option value="1">1</option>
|
||||
<option value="2">2</option>
|
||||
<option value="3">3</option>
|
||||
<option value="4" selected>4</option>
|
||||
<option value="5">5</option>
|
||||
<option value="6">6</option>
|
||||
<option value="7">7</option>
|
||||
</select>
|
||||
<br> <br>
|
||||
<button type="submit">Lancer Fabrication</button>
|
||||
</form>
|
||||
</center>
|
||||
</body></html>'
|
||||
|
||||
function urldecode() { : "${*//+/ }"; echo -e "${_//%/\\x}"; }
|
||||
|
||||
#### LOG REDIRECTION
|
||||
echo "=================================================="
|
||||
echo "G1BILLET x 6 : $HNAME:33101"
|
||||
echo "G1BILLET+ x 6 : $HNAME:33101/?montant=0&style=_&dice=4"
|
||||
echo "ZENCARD : $HNAME:33101/?montant=10&style=saubole"
|
||||
echo "ZENCARD+TW : $HNAME:33101/?montant=0&style=astro${RANDOM}@yopmail.com"
|
||||
echo "=================================================="
|
||||
echo "LOG : tail -f ${MY_PATH}/tmp/G1BILLETS.log"
|
||||
echo "=================================================="
|
||||
mkdir -p ${MY_PATH}/tmp
|
||||
exec 2>&1 >> ${MY_PATH}/tmp/G1BILLETS.log
|
||||
|
||||
#####################################################################
|
||||
########### daemon loop
|
||||
#####################################################################
|
||||
while true; do
|
||||
echo "============= ************ =========================="
|
||||
echo " STARTING $ME DAEMON READY $(date)"
|
||||
echo "============= ************ =========================="
|
||||
|
||||
REQ=$(echo "$HTTPWELLCOME" | nc -l -p 33101 -q 1) ## # WAIT FOR 33101 PORT CONTACT
|
||||
|
||||
MOATS=$(date -u +"%Y%m%d%H%M%S%4N")
|
||||
start=`date +%s`
|
||||
|
||||
URL=$(echo "$REQ" | grep '^GET' | cut -d ' ' -f2 | cut -d '?' -f2)
|
||||
HOSTP=$(echo "$REQ" | grep '^Host:' | cut -d ' ' -f2 | cut -d '?' -f2)
|
||||
HOST=$(echo "$HOSTP" | cut -d ':' -f 1)
|
||||
|
||||
echo "=================================================="
|
||||
echo "$ME RUN $(date)"
|
||||
echo "=========== %%%%%%%%%%%%%%% =============="
|
||||
echo "$REQ"
|
||||
echo "=========== %%%%%%%%%%%%%%% =============="
|
||||
echo "$URL"
|
||||
echo "=================================================="
|
||||
|
||||
## DECODING RECEIVED URL
|
||||
arr=(${URL//[=&]/ })
|
||||
# PARAM (x 3) EXTRACT "¶m=value"
|
||||
ONE=$(urldecode ${arr[0]} | xargs); TWO=$(urldecode ${arr[2]} | xargs); X=$(urldecode ${arr[4]} | xargs);
|
||||
MONTANT=$(urldecode ${arr[1]} | xargs); STYLE=$(urldecode ${arr[3]} | xargs); XPARM=$(urldecode ${arr[5]} | xargs);
|
||||
echo "DECODED : $ONE=$MONTANT & $TWO=$STYLE & $X=$XPARM"
|
||||
|
||||
[[ $STYLE == "dice" ]] && STYLE="_" && XPARM=$X ## /?montant=0&type=&dice=1
|
||||
|
||||
# EXECUTE COMMAND
|
||||
#####################################################################
|
||||
echo ${MY_PATH}/${ME} '"'$MONTANT'"' '"'$STYLE'"' '"'$XPARM'"'
|
||||
#####################################################################
|
||||
# EXECUTE COMMAND
|
||||
|
||||
LOG=$(${MY_PATH}/${ME} "$MONTANT" "$STYLE" "$XPARM")
|
||||
echo "$LOG"
|
||||
# EXTRACT VALUES FROM SELF LOG
|
||||
IPNS=$(echo "$LOG" | grep '/ipns/')
|
||||
[[ $IPNS ]] && echo "TW IPNS : $IPNS"
|
||||
CURL=$(echo "$LOG" | grep -w curl)
|
||||
[[ $IPNS ]] && echo "LIEN ACTIVATION : $CURL"
|
||||
echo "=========" ## LAST LINE INFORMATION
|
||||
ZFILE=$(echo "$LOG" | tail -n 1) ### LAST LINE : INFORM DAEMON
|
||||
echo $ZFILE
|
||||
echo "========="
|
||||
|
||||
### AUCUN RESULTAT
|
||||
if [[ ! -s $ZFILE ]]; then
|
||||
(
|
||||
echo "HTTP/1.1 200 OK
|
||||
Access-Control-Allow-Origin: ${myASTROPORT}
|
||||
Access-Control-Allow-Credentials: true
|
||||
Access-Control-Allow-Methods: GET
|
||||
Server: Astroport.ONE
|
||||
Content-Type: text/html; charset=UTF-8
|
||||
|
||||
<h1>ERROR $ZFILE</h1>" | nc -l -p 33102 -q 1 > /dev/null 2>&1 \
|
||||
&& rm -f "${MY_PATH}/tmp/http.${MOATS}"
|
||||
) &
|
||||
|
||||
else ## FILE IS FOUND
|
||||
|
||||
# PREPARE FILE SENDING
|
||||
FILE_NAME="$(basename "${ZFILE}")"
|
||||
EXT="${FILE_NAME##*.}"
|
||||
BSIZE=$(du -b "${ZFILE}" | awk '{print $1}' | tail -n 1)
|
||||
|
||||
# KILL OLD 33102 - USE IT IF YOU ( publishing )&
|
||||
pidportinuse=$(lsof -i :33102 | tail -n 1 | awk '{print $2}')
|
||||
[[ $pidportinuse ]] && kill -9 $pidportinuse && echo "KILLING NOT COLLECTED THREAD $pidportinuse"
|
||||
|
||||
# HTTP/1.1 200 OK
|
||||
echo 'HTTP/1.1 200 OK
|
||||
Access-Control-Allow-Origin: *
|
||||
Access-Control-Allow-Credentials: true
|
||||
Access-Control-Allow-Methods: GET
|
||||
Server: Astroport.G1BILLET
|
||||
Cache-Control: public
|
||||
Content-Transfer-Encoding: Binary
|
||||
Content-Length:'${BSIZE}'
|
||||
Content-Disposition: attachment; filename='${FILE_NAME}'
|
||||
' > ${MY_PATH}/tmp/http.${MOATS}
|
||||
|
||||
cat ${ZFILE} >> ${MY_PATH}/tmp/http.${MOATS}
|
||||
|
||||
# NETCAT PUBLISH port=33102
|
||||
echo "PUBLISHING ${MOATS} : $RNAME"
|
||||
|
||||
if [[ $XDG_SESSION_TYPE != 'x11' ]]; then
|
||||
(
|
||||
cat ${MY_PATH}/tmp/http.${MOATS} | nc -l -p 33102 -q 1 > /dev/null 2>&1 \
|
||||
&& rm -f "${MY_PATH}/tmp/http.${MOATS}" \
|
||||
&& rm -f "${ZFILE}" \
|
||||
&& rm -Rf "${ZFILE%.*}" \
|
||||
&& echo "G1BILLETS FILE CONSUMED"
|
||||
) &
|
||||
else
|
||||
rm -f "${MY_PATH}/tmp/http.${MOATS}" \
|
||||
&& rm -f "${ZFILE}" \
|
||||
&& rm -Rf "${ZFILE%.*}" \
|
||||
&& echo "G1BILLETS FILE CONSUMED"
|
||||
fi
|
||||
|
||||
end=`date +%s`
|
||||
dur=`expr $end - $start`
|
||||
echo "G1BILLET GENERATION WAS $dur SECONDS"
|
||||
|
||||
fi
|
||||
|
||||
## EMPTY YESTERDAY TMP FILES
|
||||
find ${MY_PATH}/tmp -mtime +1 -exec rm -Rf '{}' \;
|
||||
|
||||
done
|
||||
#####################################################################
|
||||
## loop ###############################################################TITLE="${file%.*}"
|
||||
#####################################################################
|
||||
|
||||
fi
|
||||
|
||||
exit 0
|
||||
UNIQID="$2"
|
||||
STYLE="$3"
|
||||
|
||||
## PLANCHE DE 6 BILLETS PAR DEFAUT
|
||||
NBbillets=6
|
||||
|
||||
[[ $MONTANT == "" ]] && MONTANT="___"
|
||||
[[ $UNIQID == "" ]] && UNIQID=$(date -u +%s%N | cut -b1-13)$RANDOM
|
||||
[[ "$STYLE" == "xbian" ]] && NBbillets=1 ## STYLE=xbian => 1 BILLET
|
||||
[[ "$STYLE" == "1" ]] && NBbillets=1 && STYLE="" ## 1 BILLET
|
||||
|
||||
# CHECK IF $STYLE IMAGES EXIST
|
||||
[[ ! -f ${MY_PATH}/images/fond${STYLE}.jpg ]] && exit 1
|
||||
[[ ! -f ${MY_PATH}/images/g1${STYLE}.png ]] && exit 1
|
||||
[[ ! -f ${MY_PATH}/images/logo${STYLE}.png ]] && exit 1
|
||||
|
||||
# CREATION DE $NBbillets BILLETS DE $MONTANT DU
|
||||
boucle=0;
|
||||
while [ $boucle -lt $NBbillets ]
|
||||
do
|
||||
boucle=$((boucle+1))
|
||||
NUMBER=$(${MY_PATH}/diceware.sh 4 | xargs)
|
||||
SECRET=$(${MY_PATH}/diceware.sh 4 | xargs)
|
||||
|
||||
# CREATION CLEF BILLET
|
||||
BILLETPUBKEY=$(python3 ${MY_PATH}/key_create_dunikey.py "$NUMBER" "$SECRET")
|
||||
rm -f /tmp/secret.dunikey
|
||||
|
||||
mkdir -p "/tmp/g1billet/${UNIQID}"
|
||||
# CREATION FICHIER IMAGE BILLET
|
||||
$(${MY_PATH}/MAKE_G1BILLET.sh "${NUMBER}" "${SECRET}" "${MONTANT}" "${BILLETPUBKEY}" "${UNIQID}" "${STYLE}")
|
||||
|
||||
done
|
||||
|
||||
# MONTAGE DES IMAGES DES BILLETS VERS /tmp/g1billet/${UNIQID}.pdf
|
||||
montage /tmp/g1billet/${UNIQID}/*.jpg -tile 2x3 -geometry 964x459 /tmp/g1billet/${UNIQID}.pdf
|
||||
# NB!! if "not autorized" then edit /etc/ImageMagick-6/policy.xml and comment
|
||||
# <!-- <policy domain="coder" rights="none" pattern="PDF" /> -->
|
||||
|
||||
# CLEANING TEMP FILES
|
||||
rm -Rf /tmp/g1billet/${UNIQID}
|
||||
|
||||
# ALLOWS ANY USER TO DELETE
|
||||
chmod 777 /tmp/g1billet/${UNIQID}.pdf
|
||||
|
||||
exit
|
||||
|
|
309
MAKE_G1BILLET.sh
|
@ -12,276 +12,79 @@ ME="${0##*/}"
|
|||
############################################################################################################################################################
|
||||
# ${MY_PATH}/G1BILLET_MAKE.sh "nu me ro test" "se cr et" 100 7sn9dKeCNEsHmqm1gMWNREke4YAWtNw8KG1YBSN8CmSh 97968583
|
||||
############################################################################
|
||||
export PATH="$HOME/.local/bin:$PATH"
|
||||
|
||||
## SEND LOG TO ~/.zen/tmp/_12345.log
|
||||
exec 2>&1 >> ~/.zen/G1BILLET/tmp/G1BILLETS.log
|
||||
|
||||
## LOAD PERSONAL OR DEFAULT STYLES
|
||||
[[ -d ${MY_PATH}/_images/_/ ]] \
|
||||
&& IMAGES="_images" \
|
||||
|| IMAGES="images"
|
||||
|
||||
echo "$ME ~~~~~~~~~~~~~~~ @@@@@@ -------"
|
||||
SECRET1="$1"
|
||||
echo SECRET1=${SECRET1}
|
||||
SECRET2="$2"
|
||||
echo SECRET2=${SECRET2}
|
||||
NUMERO="$1"
|
||||
SECRET="$2"
|
||||
MONTANT="$3"
|
||||
echo MONTANT=${MONTANT}
|
||||
NOTERIB="$4"
|
||||
echo NOTERIB=${NOTERIB}
|
||||
UNIQID="$5"
|
||||
echo UNIQID=${UNIQID}
|
||||
STYLE="$6"
|
||||
echo STYLE=${STYLE}
|
||||
ASTRONS="$7"
|
||||
echo ASTRONS=${ASTRONS}
|
||||
EMAIL="$8"
|
||||
echo EMAIL=${EMAIL}
|
||||
|
||||
if [[ "${SECRET1}" == "" || "$SECRET2" == "" || "$MONTANT" == "" || "$NOTERIB" == "" || "$UNIQID" == "" ]]
|
||||
if [[ "$NUMERO" == "" || "$SECRET" == "" || "$MONTANT" == "" || "$NOTERIB" == "" || "$UNIQID" == "" ]]
|
||||
then
|
||||
echo "ERROR MISSING PARAM"
|
||||
exit 1
|
||||
exit 1
|
||||
fi
|
||||
|
||||
TAB=(${SECRET1} ${SECRET2})
|
||||
FULLDICE=${#TAB[@]}
|
||||
mkdir -p /tmp/g1billet/$UNIQID
|
||||
BILLETNAME=$(echo $NUMERO | sed 's/ /_/g')
|
||||
|
||||
mkdir -p ${MY_PATH}/tmp/g1billet/$UNIQID
|
||||
BILLETNAME=$(echo ${SECRET1} | sed 's/ /_/g')
|
||||
# Add ${MY_PATH}/images/logo.png (250px)
|
||||
composite -compose Over -gravity SouthWest -geometry +50+50 -dissolve 70% "${MY_PATH}/images/logo${STYLE}.png" "${MY_PATH}/images/fond${STYLE}.jpg" "/tmp/${BILLETNAME}.jpg"
|
||||
|
||||
IMAGESSTYLE="${IMAGES}/${STYLE}"
|
||||
[[ ! -d ${MY_PATH}/${IMAGESSTYLE} ]] && IMAGESSTYLE="${IMAGES}/xastro" ## DEFAULT : TOOD CREATE UPlanet Style
|
||||
# Prepare BILLET qrcode verification URL
|
||||
qrencode -s 5 -o "/tmp/g1billet/${UNIQID}/${BILLETNAME}.QR.png" "$NOTERIB"
|
||||
|
||||
# Prepare June logo color
|
||||
# Add verification QRCode
|
||||
composite -compose Over -gravity SouthEast -geometry +45+60 "/tmp/g1billet/${UNIQID}/${BILLETNAME}.QR.png" "/tmp/${BILLETNAME}.jpg" "/tmp/${BILLETNAME}.jpg"
|
||||
|
||||
# Change June logo color
|
||||
case "$MONTANT" in
|
||||
1)
|
||||
convert "${MY_PATH}/${IMAGESSTYLE}/fond.jpg" -fuzz 20% -fill grey -opaque '#17b317' "${MY_PATH}/tmp/g1billet/${UNIQID}/fond.jpg"
|
||||
;;
|
||||
2)
|
||||
convert "${MY_PATH}/${IMAGESSTYLE}/fond.jpg" -fuzz 20% -fill green -opaque '#17b317' "${MY_PATH}/tmp/g1billet/${UNIQID}/fond.jpg"
|
||||
;;
|
||||
5)
|
||||
convert "${MY_PATH}/${IMAGESSTYLE}/fond.jpg" -fuzz 20% -fill orange -opaque '#17b317' "${MY_PATH}/tmp/g1billet/${UNIQID}/fond.jpg"
|
||||
;;
|
||||
10)
|
||||
convert "${MY_PATH}/${IMAGESSTYLE}/fond.jpg" -fuzz 20% -fill blue -opaque '#17b317' "${MY_PATH}/tmp/g1billet/${UNIQID}/fond.jpg"
|
||||
;;
|
||||
20)
|
||||
convert "${MY_PATH}/${IMAGESSTYLE}/fond.jpg" -fuzz 20% -fill purple -opaque '#17b317' "${MY_PATH}/tmp/g1billet/${UNIQID}/fond.jpg"
|
||||
;;
|
||||
50)
|
||||
convert "${MY_PATH}/${IMAGESSTYLE}/fond.jpg" -fuzz 20% -fill red -opaque '#17b317' "${MY_PATH}/tmp/g1billet/${UNIQID}/fond.jpg"
|
||||
;;
|
||||
100)
|
||||
convert "${MY_PATH}/${IMAGESSTYLE}/fond.jpg" -fuzz 20% -fill black -opaque '#17b317' "${MY_PATH}/tmp/g1billet/${UNIQID}/fond.jpg"
|
||||
;;
|
||||
*)
|
||||
cp "${MY_PATH}/${IMAGESSTYLE}/fond.jpg" "${MY_PATH}/tmp/g1billet/${UNIQID}/fond.jpg"
|
||||
;;
|
||||
1)
|
||||
convert "${MY_PATH}/images/g1${STYLE}.png" -fuzz 20% -fill grey -opaque '#e5912b' "/tmp/g1billet/${UNIQID}/g1.png"
|
||||
;;
|
||||
2)
|
||||
convert "${MY_PATH}/images/g1${STYLE}.png" -fuzz 20% -fill green -opaque '#e5912b' "/tmp/g1billet/${UNIQID}/g1.png"
|
||||
;;
|
||||
5)
|
||||
convert "${MY_PATH}/images/g1${STYLE}.png" -fuzz 20% -fill orange -opaque '#e5912b' "/tmp/g1billet/${UNIQID}/g1.png"
|
||||
;;
|
||||
10)
|
||||
convert "${MY_PATH}/images/g1${STYLE}.png" -fuzz 20% -fill blue -opaque '#e5912b' "/tmp/g1billet/${UNIQID}/g1.png"
|
||||
;;
|
||||
20)
|
||||
convert "${MY_PATH}/images/g1${STYLE}.png" -fuzz 20% -fill purple -opaque '#e5912b' "/tmp/g1billet/${UNIQID}/g1.png"
|
||||
;;
|
||||
50)
|
||||
convert "${MY_PATH}/images/g1${STYLE}.png" -fuzz 20% -fill red -opaque '#e5912b' "/tmp/g1billet/${UNIQID}/g1.png"
|
||||
;;
|
||||
100)
|
||||
convert "${MY_PATH}/images/g1${STYLE}.png" -fuzz 20% -fill black -opaque '#e5912b' "/tmp/g1billet/${UNIQID}/g1.png"
|
||||
;;
|
||||
*)
|
||||
cp "${MY_PATH}/images/g1${STYLE}.png" "/tmp/g1billet/${UNIQID}/g1.png"
|
||||
;;
|
||||
esac
|
||||
|
||||
## UPPER RIGHT SIGN (g1.png)
|
||||
cp "${MY_PATH}/${IMAGESSTYLE}/g1.png" "${MY_PATH}/tmp/g1billet/${UNIQID}/g1.png"
|
||||
|
||||
## ♥Box :: ZENCARD or ASTROID
|
||||
|
||||
BOTTOM="$(date) :: ♥Box :: _G1BILLET_ :: $(hostname) ::"
|
||||
XZUID="__________@__________"
|
||||
|
||||
## PGP @PASS QRCODE
|
||||
## NOT G1BILLET v1 : Create EXTRA PGP QR
|
||||
if [[ "${STYLE:0:1}" != "_" && "${STYLE:0:1}" != "@" && ! "${STYLE}" =~ ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$ ]]; then
|
||||
|
||||
USALT=$(echo "${SECRET1}" | jq -Rr @uri)
|
||||
UPEPPER=$(echo "$SECRET2" | jq -Rr @uri)
|
||||
## SECURED RANDOM salt : pepper GPG SEQUENCE
|
||||
s=$(${MY_PATH}/diceware.sh 1 | xargs)
|
||||
p=$(${MY_PATH}/diceware.sh 1 | xargs)
|
||||
|
||||
echo "(≖‿‿≖) PGP /?${s}=${USALT}&${p}=${UPEPPER} (PASS=$UNIQID)"
|
||||
echo "/?${s}=${USALT}&${p}=${UPEPPER}" > ${MY_PATH}/tmp/topgp
|
||||
cat ${MY_PATH}/tmp/topgp | gpg --symmetric --armor --batch --passphrase "$UNIQID" -o ${MY_PATH}/tmp/gpg.${BILLETNAME}.asc
|
||||
rm ${MY_PATH}/tmp/topgp ## CLEANING CACHE
|
||||
|
||||
DISCO="$(cat ${MY_PATH}/tmp/gpg.${BILLETNAME}.asc | tr '-' '~' | tr '\n' '-' | tr '+' '_' | jq -Rr @uri )"
|
||||
# [[ ${STYLE} == "UPlanet" ]] && DISCO="$(cat ${MY_PATH}/tmp/gpg.${BILLETNAME}.asc | tr '-' '&' | tr '\n' '-' | tr '+' '_' | jq -Rr @uri )" ## & ẑencard = (email/8digit)+4digit ## CALLED FROM VISA.new
|
||||
|
||||
echo "$DISCO"
|
||||
|
||||
## Put astrologo_nb in QRCode
|
||||
cp ${MY_PATH}/${IMAGES}/astrologo_nb.png ${MY_PATH}/tmp/fond.png
|
||||
|
||||
## MAKE amzqr WITH astro:// LINK
|
||||
amzqr -d ${MY_PATH}/tmp \
|
||||
-l H \
|
||||
-p ${MY_PATH}/tmp/fond.png \
|
||||
"$DISCO" \
|
||||
|| qrencode -s 6 -o "${MY_PATH}/tmp/fond_qrcode.png" "$DISCO"
|
||||
|
||||
## ADD PLAYER EMAIL
|
||||
convert -gravity southeast -pointsize 28 -fill black -draw "text 5,3 \"${EMAIL}\"" ${MY_PATH}/tmp/fond_qrcode.png ${MY_PATH}/tmp/g1billet/${UNIQID}/${BILLETNAME}.ZENCARD.png
|
||||
convert ${MY_PATH}/tmp/g1billet/${UNIQID}/${BILLETNAME}.ZENCARD.png -resize 320 ${MY_PATH}/tmp/g1billet/${UNIQID}/320.png
|
||||
|
||||
rm ${MY_PATH}/tmp/gpg.${BILLETNAME}.asc
|
||||
# Add June LOGO to Billet
|
||||
composite -compose Over -gravity NorthEast -geometry +50+25 -dissolve 90% "/tmp/g1billet/${UNIQID}/g1.png" "/tmp/${BILLETNAME}.jpg" "/tmp/${BILLETNAME}.jpg"
|
||||
|
||||
# xbian style (ASTROPORT/KODI)
|
||||
if [[ "${STYLE}" == "xbian" ]]
|
||||
then
|
||||
# CREATE PSEUDO for Gchange.fr
|
||||
XZUID=$(${MY_PATH}/diceware.sh 1 | xargs)${RANDOM:0:2}$(${MY_PATH}/diceware.sh 1 | xargs)
|
||||
BOTTOM="ASTROPORT KODI --- https://gchange.fr ---"
|
||||
else
|
||||
XZUID="G1 BILLET"
|
||||
BOTTOM="Porte Monnaie Libre!! Utilisez avec https://cesium.app"
|
||||
fi
|
||||
|
||||
## TW moa net
|
||||
TWIMG="moa_net.png"
|
||||
|
||||
# ZENCARD+@ linked to G1BIILET ipns
|
||||
[[ "${STYLE:0:1}" == "@" ]] \
|
||||
&& TWIMG="pirate_map.png"
|
||||
|
||||
## G1BILLET+ linked to .current PLAYER TW (patch for Linkedin Fred)
|
||||
[[ "${STYLE:0:1}" == "_" ]] \
|
||||
&& ASTRONS="" \
|
||||
&& TWIMG="web_internet.png"
|
||||
|
||||
if [[ ${ASTRONS} != "" ]] ; then
|
||||
ASTROLINK="${ASTRONS}"
|
||||
else
|
||||
ASTROLINK="https://opencollective.com/made-in-zen"
|
||||
fi
|
||||
|
||||
amzqr "${ASTROLINK}" \
|
||||
-l H -p "$MY_PATH/${IMAGES}/${TWIMG}" \
|
||||
-c -n QRTWavatar.png \
|
||||
-d ${MY_PATH}/tmp/g1billet/${UNIQID}/ \
|
||||
|| qrencode -s 6 -o "${MY_PATH}/tmp/g1billet/${UNIQID}/QRTWavatar.png" "${ASTROLINK}"
|
||||
|
||||
convert ${MY_PATH}/tmp/g1billet/${UNIQID}/QRTWavatar.png -resize 280 ${MY_PATH}/tmp/g1billet/${UNIQID}/TW.${ASTRONS}.png
|
||||
|
||||
|
||||
[[ "${EMAIL}" != "" ]] && XZUID="${EMAIL}"
|
||||
|
||||
## ♥Box :: G1BILLET+ :: ZENCARD :: G1(TW)
|
||||
|
||||
# GIBILLET dice > 3 => G1BILLET+
|
||||
[[ "${STYLE:0:1}" == "_" ]] \
|
||||
&& mv ${MY_PATH}/tmp/g1billet/${UNIQID}/TW.${ASTRONS}.png ${MY_PATH}/tmp/g1billet/${UNIQID}/LEFT.png \
|
||||
&& BOTTOM="$(date) :: ♥Box :: ẐBILLET+ :: $(hostname) ::"
|
||||
|
||||
[[ "${STYLE:0:1}" != "_" ]] \
|
||||
&& mv ${MY_PATH}/tmp/g1billet/${UNIQID}/320.png ${MY_PATH}/tmp/g1billet/${UNIQID}/LEFT.png \
|
||||
&& BOTTOM="$(date) :: ♥Box :: ZENCARD :: $(hostname) ::"
|
||||
|
||||
[[ "${STYLE:0:1}" == "x" ]] \
|
||||
&& mv ${MY_PATH}/tmp/g1billet/${UNIQID}/TW.${ASTRONS}.png ${MY_PATH}/tmp/g1billet/${UNIQID}/CENTER.png \
|
||||
&& BOTTOM="$(date) :: ♥Box :: ZENCARD+TW :: $(hostname) ::"
|
||||
|
||||
[[ "${STYLE}" == "UPlanet" ]] \
|
||||
&& mv ${MY_PATH}/tmp/g1billet/${UNIQID}/TW.${ASTRONS}.png ${MY_PATH}/tmp/g1billet/${UNIQID}/CENTER.png \
|
||||
&& BOTTOM="$(date) :: ♥UPLANET :: MADE-IN-ZEN :: $(hostname) ::"
|
||||
|
||||
if [[ "${STYLE:0:1}" == "@" || "${STYLE}" =~ ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$ ]] ; then
|
||||
#~ ########################## G1Voeu _ G1BILLET linking ##
|
||||
## Astroport.ONE LINKING :: STYLE=EMAIL :: ZENCARD+@
|
||||
# CREATE @PASS (G1G1BILLET+ G1Voeu derivated keys)
|
||||
|
||||
MOATS=$(date -u +"%Y%m%d%H%M%S%4N")
|
||||
SRCMAIL=$(cat ~/.zen/game/players/.current/.player 2>/dev/null)
|
||||
G1PUB=$(cat ~/.zen/game/players/.current/.g1pub 2>/dev/null)
|
||||
|
||||
#~ ## GET current PLAYER G1PUB
|
||||
[[ -d ~/.zen/game/players/${STYLE} ]] \
|
||||
&& SRCMAIL=${STYLE} && G1PUB=$(cat ~/.zen/game/players/${STYLE}/.g1pub 2>/dev/null)
|
||||
|
||||
BILLETFULLNAME=$(echo "${SRCMAIL} ${SECRET1} ${SECRET2}" | sed 's/ /_/g') # em@ai.l_dice_words
|
||||
|
||||
#### VOEUX.print.sh G1BILLET+
|
||||
echo ~/.zen/Astroport.ONE/tools/VOEUX.print.sh "${BILLETFULLNAME}" "G1BILLET+" "${MOATS}" "${G1PUB}"
|
||||
NEWIMAGIC=$(~/.zen/Astroport.ONE/tools/VOEUX.print.sh "${BILLETFULLNAME}" "G1BILLET+" "${MOATS}" "${G1PUB}" | tail -n 1)
|
||||
convert ~/.zen/tmp/${MOATS}/START.png -resize 300 ${MY_PATH}/tmp/g1billet/${UNIQID}/LEFT.png
|
||||
|
||||
#~ ## REPLACE fond.jpg WITH moa.jpg from TW "Dession de PLAYER"
|
||||
[[ -s ~/.zen/game/players/${SRCMAIL}/moa.jpg ]] \
|
||||
&& rm ${MY_PATH}/tmp/g1billet/${UNIQID}/fond.jpg \
|
||||
&& convert ~/.zen/game/players/${SRCMAIL}/moa.jpg -resize 964x459 -background grey -gravity center -extent 964x459 ${MY_PATH}/tmp/g1billet/${UNIQID}/fond.jpg
|
||||
|
||||
mv ${MY_PATH}/tmp/g1billet/${UNIQID}/TW.${ASTRONS}.png ${MY_PATH}/tmp/g1billet/${UNIQID}/CENTER.png
|
||||
|
||||
BILLNS=$(ipfs key import ${NOTERIB} -f pem-pkcs8-cleartext ~/.zen/tmp/${MOATS}/G1BILLET+.EXTRA.ipfskey)
|
||||
#SIGN & HIDE SECRETS
|
||||
#~ NOTERIB="https://ipfs.asycn.io/ipns/$BILLNS"
|
||||
XZUID=${SRCMAIL}
|
||||
BOTTOM="$(date) :: ♥Box :: ZENCARD+@ :: $(hostname) ::"
|
||||
|
||||
fi
|
||||
|
||||
# ADD ASTROID LINK
|
||||
|
||||
# OVERLAY LOGO over FOND (logo.png)
|
||||
composite -compose Over -dissolve 70% \
|
||||
"${MY_PATH}/${IMAGESSTYLE}/logo.png" \
|
||||
"${MY_PATH}/tmp/g1billet/${UNIQID}/fond.jpg" \
|
||||
"${MY_PATH}/tmp/${BILLETNAME}.jpg"
|
||||
|
||||
### TEXT OVERLAY
|
||||
#~ -pointsize 22 -draw 'text 50,100 "'"Secret 1: ${SECRET1}"'"' \
|
||||
#~ -pointsize 22 -fill black -draw 'text 50,130 "'"Secret 2: $SECRET2"'"' \
|
||||
|
||||
if [[ "${STYLE:0:1}" != "_" && "${STYLE:0:1}" != "x" && ${MONTANT} != "___" ]]; then
|
||||
convert -font 'Liberation-Sans' \
|
||||
-pointsize 40 -fill black -draw 'text 70,50 "'"$XZUID"'"' \
|
||||
-pointsize 150 -fill black -draw 'text 120,380 "'"$MONTANT"'"' \
|
||||
-pointsize 20 -fill black -draw 'text 340,22 "'"${NOTERIB}"'"' \
|
||||
-pointsize 25 -fill black -draw 'text 50,440 "'"$BOTTOM"'"' \
|
||||
"${MY_PATH}/tmp/${BILLETNAME}.jpg" "${MY_PATH}/tmp/g1billet/${UNIQID}/${BILLETNAME}.BILLET.jpg"
|
||||
else
|
||||
convert -font 'Liberation-Sans' \
|
||||
-pointsize 35 -fill black -draw 'text 50,56 "'"$XZUID"'"' \
|
||||
-pointsize 22 -fill black -draw 'text 300,26 "'"${NOTERIB}"'"' \
|
||||
-pointsize 22 -fill black -draw 'text 50,85 "'"(Secret 1) ${SECRET1}"'"' \
|
||||
-pointsize 22 -fill black -draw 'text 50,105 "'"(Secret 2) $SECRET2"'"' \
|
||||
-pointsize 25 -fill grey -draw 'text 50,440 "'"$BOTTOM"'"' \
|
||||
"${MY_PATH}/tmp/${BILLETNAME}.jpg" "${MY_PATH}/tmp/g1billet/${UNIQID}/${BILLETNAME}.BILLET.jpg"
|
||||
fi
|
||||
|
||||
rm -f ${MY_PATH}/tmp/${BILLETNAME}.jpg
|
||||
|
||||
## ADD SouthWEST
|
||||
[[ -s "${MY_PATH}/tmp/g1billet/${UNIQID}/LEFT.png" ]] && \
|
||||
composite -compose Over -gravity SouthWest -geometry +30+30 \
|
||||
"${MY_PATH}/tmp/g1billet/${UNIQID}/LEFT.png" \
|
||||
"${MY_PATH}/tmp/g1billet/${UNIQID}/${BILLETNAME}.BILLET.jpg" \
|
||||
"${MY_PATH}/tmp/g1billet/${UNIQID}/${BILLETNAME}.BILLET.jpg"
|
||||
|
||||
## ADD CENTER QRCODE
|
||||
[[ -s "${MY_PATH}/tmp/g1billet/${UNIQID}/CENTER.png" ]] && \
|
||||
composite -compose Over -gravity Center -geometry +30+40 \
|
||||
"${MY_PATH}/tmp/g1billet/${UNIQID}/CENTER.png" \
|
||||
"${MY_PATH}/tmp/g1billet/${UNIQID}/${BILLETNAME}.BILLET.jpg" \
|
||||
"${MY_PATH}/tmp/g1billet/${UNIQID}/${BILLETNAME}.BILLET.jpg"
|
||||
|
||||
# G1PUB QR CODE RIGHT
|
||||
[[ -s ${HOME}/.zen/Astroport.ONE/images/zenticket.png ]] \
|
||||
&& amzqr "${NOTERIB}" -l H -p "${HOME}/.zen/Astroport.ONE/images/zenticket.png" -c -n QR.png -d ${MY_PATH}/tmp/g1billet/${UNIQID}/ \
|
||||
&& convert ${MY_PATH}/tmp/g1billet/${UNIQID}/QR.png -resize 250 ${MY_PATH}/tmp/g1billet/${UNIQID}/${BILLETNAME}.QR.png \
|
||||
&& rm ${MY_PATH}/tmp/g1billet/${UNIQID}/QR.png \
|
||||
|| qrencode -s 6 -o "${MY_PATH}/tmp/g1billet/${UNIQID}/${BILLETNAME}.QR.png" "$NOTERIB"
|
||||
|
||||
# AJOUT DU G1PUB QRCODE A DROITE DU BILLET
|
||||
composite -compose Over -gravity SouthEast -geometry +35+50 \
|
||||
"${MY_PATH}/tmp/g1billet/${UNIQID}/${BILLETNAME}.QR.png" \
|
||||
"${MY_PATH}/tmp/g1billet/${UNIQID}/${BILLETNAME}.BILLET.jpg" \
|
||||
"${MY_PATH}/tmp/g1billet/${UNIQID}/${BILLETNAME}.BILLET.jpg"
|
||||
|
||||
# Add g1.png SIGLE
|
||||
[[ "${STYLE:0:1}" != "@" && ! "${STYLE}" =~ ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$ ]] && \
|
||||
composite -compose Over -dissolve 90% \
|
||||
"${MY_PATH}/tmp/g1billet/${UNIQID}/g1.png" \
|
||||
"${MY_PATH}/tmp/g1billet/${UNIQID}/${BILLETNAME}.BILLET.jpg" \
|
||||
"${MY_PATH}/tmp/g1billet/${UNIQID}/${BILLETNAME}.BILLET.jpg"
|
||||
|
||||
echo "$ME ~~~~~~~~~~~~~~~ @@@@@@ -------"
|
||||
|
||||
## BILLET READY in ${MY_PATH}/tmp/g1billet/${UNIQID}/${BILLETNAME}.BILLET.jpg
|
||||
## NOT TO BE IN FINAL PDF (getting all jpg)
|
||||
rm "${MY_PATH}/tmp/g1billet/${UNIQID}/fond.jpg"
|
||||
|
||||
exit 0
|
||||
-pointsize 120 -fill black -draw 'text 330,250 "'"$MONTANT DU"'"' \
|
||||
-pointsize 40 -fill black -draw 'text 75,50 "'"$XZUID"'"' \
|
||||
-pointsize 30 -draw 'text 50,100 "'"Identifiant: $NUMERO"'"' \
|
||||
-pointsize 22 -fill black -draw 'text 50,130 "'"Code Secret: $SECRET"'"' \
|
||||
-pointsize 25 -fill black -draw 'text 150,440 "'"$BOTTOM"'"' \
|
||||
"/tmp/${BILLETNAME}.jpg" "/tmp/g1billet/${UNIQID}/${BILLETNAME}.BILLET.jpg"
|
||||
|
||||
rm -f /tmp/${BILLETNAME}.jpg
|
||||
|
|
224
README.md
|
@ -1,238 +1,82 @@
|
|||
# G1BILLET
|
||||
|
||||
## Présentation
|
||||
Ce code est un générateur de G1BILLETS qui utilise duniter.py keygen imagemagik amzqr
|
||||
Ce code est un générateur de G1BILLETS
|
||||
|
||||
Il lance la fabrication de "G1 Portefeuilles" vides à remplir soi-même !
|
||||
Les G1Billets sont assemblés dans un fichier PDF pour les imprimer facilement sur une imprimante A4 et vous en servir comme chéquier.
|
||||
Il lance la fabrication de six "G1 Portefeuilles" vides à remplir soi-même !
|
||||
Les G1Billets sont assemblés dans un fichier PDF pour les imprimer facilement sur une imprimante A4
|
||||
|
||||
Avant de vous en servir, utilisez Cesium pour flasher le QR Code et effectuer le virement correspondant à son montant sur chaque portefeuille.
|
||||
Ensuite, offrez ces G1Billets à qui vous voulez.
|
||||
Ensuite, offrez ces G1 Billets à qui vous voulez.
|
||||
|
||||
Son détenteur peut alors utiliser l'identifiant/mot de passe pour accéder au portefeuille correspondant.
|
||||
|
||||
Chaque billet est composé des images ```fond.jpg g1.png logo.png``` (à modifier ou remplacer par les votres) y sont ensuite ajouté différents signes et qrcodes.
|
||||
|
||||
En utilisant le style "xbian" vous activez le mode "ZenCard".
|
||||
Un G1BILLET sécurisé qui fonctionne sur les [♥Box Ğ1Station](https://pad.p2p.legal/s/Astroport.ONE).
|
||||
|
||||
|
||||
Son détenteur peut alors utiliser l'identifiant/mot de passe pour contrôler la clef du portefeuille correspondant.
|
||||
|
||||
* [FIL DE DISCUSSION SUR LE FORUM MONNAIE LIBRE](https://forum.monnaie-libre.fr/t/nouveau-g1-billets/14529?u=qoop)
|
||||
* [VIDEO ZenCard TEASER](https://tube.p2p.legal/w/oBufWkzT3whWk3GabX3GAD)
|
||||
|
||||
> :warning: **Pour utiliser ZenCard : Installez [Astroport.ONE](https://git.p2p.legal/STI/Astroport.ONE).**
|
||||
* [DISCUSSION/FAQ/DETAILS](https://forum.monnaie-libre.fr/t/nouveau-g1-billets/14529?u=qoop)
|
||||
* [DEMO EN VIDEO](./G1BILLETS.mp4)
|
||||
|
||||
|
||||
## Utilisation
|
||||
|
||||
En ligne de commande, adaptez ces lignes à votre style ;)
|
||||
Pour une utilisation en ligne de commande, adaptez ces quelques lignes
|
||||
|
||||
```
|
||||
montant=0 # Valeur faciale à indiquer sur le billet (0 : indéfini)
|
||||
style="_" # Style du G1BILLET
|
||||
secu=7 # Nombre de mots "diceware" (corrélé à la complexité du PASS)
|
||||
./G1BILLETS.sh "$montant" "$style" "$secu"
|
||||
Montant=5 # Valeur faciale à indiquer sur le billet
|
||||
NomFichier="nom_unique_du_pdf" # Correspond au nom du fichier créé dans /tmp/g1billet/
|
||||
./G1BILLETS.sh "$Montant" "$NomFichier"
|
||||
```
|
||||
|
||||
Personnalisez vos G1Billets, en modifiant les images dans ```images/$style``` (copiez-collez celles d'autres styles pour commencer le votre)
|
||||
Pour personnaliser vos G1Billets, modifiez les images dans le répertoire du même nom (en conservant les dimensions)
|
||||
La fabrication de la planche de G1Billets depuis un site web est possible en mettant le code dans un répertoire servi par un serveur web qui gère PHP...
|
||||
|
||||
* PLANCHE de 6 : http://g1billet.localhost:33101
|
||||
* G1TICKET de 10 : http://g1billet.localhost:33101/?montant=10&style=ticket
|
||||
* ZenCard "avec dedicace" : http://g1billet.localhost:33101/?montant=0&style=votre@email.com
|
||||
## Installation
|
||||
|
||||
## Pré-requis Installation
|
||||
|
||||
Pour Linux DEBIAN, Ubuntu, recommandé: [Linux Mint](https://www.linuxmint.com/)
|
||||
Pour Linux le seul système d'opération qui respecte votre liberté
|
||||
Ma recommandation: [Linux Mint](https://www.linuxmint.com/) ou [TwisterOS](https://twisteros.com/)
|
||||
|
||||
```
|
||||
# Installer git
|
||||
sudo apt install git
|
||||
```
|
||||
|
||||
# INSTALLATION (**for Linux (systemd) only**)
|
||||
|
||||
> :warning: **Vous souhaitez utiliser ZenCard? Installez [Astroport.ONE](https://git.p2p.legal/STI/Astroport.ONE).**
|
||||
|
||||
Utiliser le mode G1BILLET (seulement).
|
||||
|
||||
```
|
||||
# Création et clonage du code dans ""~/.zen"
|
||||
mkdir -p ~/.zen
|
||||
cd ~/.zen
|
||||
# Cloner le code de G1BILLET
|
||||
mkdir -p $HOME/bin/
|
||||
cd $HOME/bin/
|
||||
git clone https://git.p2p.legal/qo-op/G1BILLET.git
|
||||
cd G1BILLET
|
||||
|
||||
# Installation
|
||||
./install.sh
|
||||
|
||||
# Activation systemd
|
||||
./setup_systemd.sh
|
||||
|
||||
## Ajouter raccourci sur votre Bureau
|
||||
~/.zen/G1BILLET/add_desktop_shortcut.sh
|
||||
|
||||
## Ouvrir "Interface Web"
|
||||
xdg-open http://localhost:33101/
|
||||
|
||||
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# CA NE FONCTIONNE PAS ?
|
||||
|
||||
Faites ces TESTS.
|
||||
|
||||
## Service is running ?
|
||||
```
|
||||
sudo systemctl status g1billet
|
||||
|
||||
● g1billet.service - G1BILLET API
|
||||
Loaded: loaded (/etc/systemd/system/g1billet.service; enabled; vendor preset: enabled)
|
||||
Active: active (running) since Thu 2023-04-20 21:11:39 CEST; 46min ago
|
||||
Main PID: 3250895 (G1BILLETS.sh)
|
||||
Tasks: 3 (limit: 18381)
|
||||
Memory: 9.4M
|
||||
CGroup: /system.slice/g1billet.service
|
||||
├─3250895 /bin/bash /home/fred/workspace/G1BILLET/G1BILLETS.sh daemon
|
||||
├─3253436 /bin/bash /home/fred/workspace/G1BILLET/G1BILLETS.sh daemon
|
||||
└─3253438 nc -l -p 33101 -q 1
|
||||
```
|
||||
|
||||
|
||||
## Crypto is working ?
|
||||
```
|
||||
./keygen 'toto' 'toto'
|
||||
EA7Dsw39ShZg4SpURsrgMaMqrweJPUFPYHwZA8e92e3D
|
||||
Ajoutez les dépendances nécessaire
|
||||
|
||||
```
|
||||
|
||||
## Graphics are OK ?
|
||||
```
|
||||
## CHANGE VARIABLES TO TEST YOUR STYLE ;)
|
||||
SALT=toto; PEPPER=toto;
|
||||
SECRET=toto; MONTANT=___;
|
||||
BILLETPUBKEY=EA7Dsw39ShZg4SpURsrgMaMqrweJPUFPYHwZA8e92e3D;
|
||||
UNIQID=toto; STYLE=xastro
|
||||
ASTRONAUTENS=k51qzi5uqu5dl1zsbaala0bi26zpl5cfi7mogjwl9cg76d8awfc1d0iv738kak
|
||||
EMAIL=toto@yopmail.com
|
||||
|
||||
BILLETNAME=$(echo $SALT | sed 's/ /_/g')
|
||||
|
||||
./MAKE_G1BILLET.sh "${SALT}" "${SECRET}" "${MONTANT}" "${BILLETPUBKEY}" "${UNIQID}" "${STYLE}" "${ASTRONAUTENS}" "${EMAIL}"
|
||||
|
||||
xdg-open tmp/g1billet/$UNIQID/$BILLETNAME.BILLET.jpg
|
||||
sudo apt install python3 python3-pip imagemagick qrencode ttf-mscorefonts-installer
|
||||
sudo pip3 install duniterpy
|
||||
```
|
||||
|
||||
* NB: Si une erreur du type "not autorized" apparait,
|
||||
éditez /etc/ImageMagick-6/policy.xml pour commenter la ligne qui bloque la création de "PDF"
|
||||
|
||||
ou réglez le problème avec ce script :
|
||||
|
||||
NB: Si une erreur du type "not autorized" apparait, vous devez autoriser la création de pdf en editant /etc/ImageMagick-6/policy.xml pour commenter la ligne:
|
||||
```
|
||||
echo "######### CORRECT IMAGEMAGICK PDF ############"
|
||||
if [[ $(cat /etc/ImageMagick-6/policy.xml | grep PDF) ]]; then
|
||||
cat /etc/ImageMagick-6/policy.xml | grep -Ev PDF > /tmp/policy.xml
|
||||
sudo cp /tmp/policy.xml /etc/ImageMagick-6/policy.xml
|
||||
fi
|
||||
<!-- <policy domain="coder" rights="none" pattern="PDF" /> -->
|
||||
```
|
||||
|
||||
## LOG monitoring
|
||||
## Support
|
||||
|
||||
```
|
||||
tail -f ~/.zen/G1BILLET/tmp/G1BILLETS.log
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# PERSONNALISATION GRAPHIQUE
|
||||
|
||||
Pour changer le fond, le logo et le sigle de votre G1BILLET
|
||||
|
||||
Créez un répertoire dont le nom commence par "_"
|
||||
et recopiez les modèles par défaut
|
||||
|
||||
```
|
||||
mkdir -p ~/.zen/G1BILLET/_images
|
||||
cp -R ~/.zen/G1BILLET/images/* ~/.zen/G1BILLET/_images
|
||||
|
||||
# Redémarrer G1BILLET
|
||||
sudo systemctl restart g1billet
|
||||
|
||||
```
|
||||
|
||||
![](https://ipfs.copylaradio.com/ipfs/QmbLcxZR8C84PiSsFDbunSDj7nVfFC6TE2B8SjYnhp6Xuo)
|
||||
|
||||
Utilisez GIMP pour modifier les images...
|
||||
|
||||
# Support : [dites nous ce qui ne fonctionne pas](/qo-op/G1BILLET/issues)
|
||||
[et ce qui fonctionne](https://pad.p2p.legal/s/G1BILLET)
|
||||
|
||||
En opérant le service G1BILLET, vous devenez "tiers de confiance".
|
||||
Vous définissez l'usage selon votre envie
|
||||
|
||||
> La planche que vous allez imprimer est un chéquier multifonction.
|
||||
|
||||
Pour lui assurer une convertibilité en Ğ1, vous devrez [les créditer en flashant leur QRCode avec Cesium](https://forum.monnaie-libre.fr/t/nouveau-g1-billets/14529/4?u=qoop).
|
||||
|
||||
Une planche contient 6 G1BILLETS qui comportent des codes d'accès à "une clef de chiffrement" donnant accès à [notre crypto zone](https://www.copylaradio.com/blog/blog-1/post/espace-et-planetes-numeriques-33). Ces billets indiquent l'emplacement, la clef publique, et la clef, privée (ou non), d'un coffre numérique s'y trouvant.
|
||||
|
||||
G1BILLET révolutionne le "BILLET" tel que nous le connaissons...
|
||||
|
||||
## Un "bon au porteur" de nouvelle génération
|
||||
|
||||
**1. Effacer le secret**
|
||||
|
||||
* Définitivement_
|
||||
|
||||
Dans le cas où plus personne ne connaît le secret, et ce qui est relié à ce G1BILLET est immuable (impossible à vider).
|
||||
|
||||
Sa valeur en G1 pourra augmenter mais celle du morceau de papier dépendra du contrôle du nombre de ses copies,
|
||||
C'est la version qui se rapproche le plus de ce que nous connaissons comme "Billet de Banque".
|
||||
Celui-ci devrait donc être détruit lorsque son émetteur le "récupère" en assurant la convertibilité promise.
|
||||
|
||||
Associé à des données multimédia, vous disposez d'un "Bon pour y accéder" que vous pouvez offrir.
|
||||
Selon la nature de ces données, devenues immuables et associables à des défis, ils sont utilisables pour "monétiser l'accès aux données".
|
||||
|
||||
* Temporairement_
|
||||
|
||||
En cachant le secret sous une couche "case à gratter" par exemple, le G1BILLET peut passer de son statut "Billet de Banque" à celui de Cadeau à accepter.
|
||||
Son contenu en G1 est alors récupérable par celui qui révèle le secret. A ce moment, l’œuvre et le portefeuille associée au G1BILLET appartiennent pleinement à son propriétaire.
|
||||
|
||||
> Garder une copie du secret ou pas.
|
||||
> C'est ce qui conditionne le premier maillon de confiance.
|
||||
|
||||
**1. Laisser le secret**
|
||||
|
||||
Dans ce cas, le "bien numérique" rattaché à ce secret est sous le contrôle de celui qui utilise ce codes, donc le possède, ou en aura fait une copie.
|
||||
Cela concerne une ressource commune et abondante pour un groupe à bon niveau de confiance relatif
|
||||
|
||||
Par exemple, on pourra s'en servir comme Kit découverte "Gchange/Cesium" à offrir à ses amis (avec de la monnaie dessus ou pas).
|
||||
|
||||
|
||||
**Essayez!! Envoyez-nous vos expériences...**
|
||||
|
||||
---
|
||||
En créant ces G1Billets, vous devenez tiers de confiance...
|
||||
|
||||
Réalisé et offert dans l'espoir que la(/les) monnaie(s) libre(s) deviennent réalité pour tous.
|
||||
|
||||
> Le saviez-vous ? Vous pouvez ouvrir un compte sur [GCHANGE](https://gchange.fr) avec les identifiants de votre G1BILLET/ZenCard.
|
||||
Il s'agit également d'un portefeuille [Cesium](https://cesium.app).
|
||||
IMPORTANT!! Invitez celles et ceux à qui vous offrez ces G1 Billets à ouvrir un compte sur [GCHANGE](https://gchange.fr) et à proposer leurs services, objets et créations.
|
||||
|
||||
> :warning: ATTENTION. N'utilisez pas ce compte pour devenir membre forgeron !
|
||||
Ou bien créez un ZenCard de haute sécurité que vous n'utiliserez que sur Cesium dans ce cas précis.
|
||||
Merci pour vos encouragements et/ou vos dons
|
||||
* [JUNE](https://demo.cesium.app/#/app/wot/DsEx1pS33vzYZg4MroyBV9hCw98j1gtHEhwiZ5tK7ech/Fred)
|
||||
* [UNL](https://opencollective.com/monnaie-libre)
|
||||
* [PAYPAL](https://www.paypal.com/paypalme/QWANTIC)
|
||||
|
||||
Merci pour vos encouragements et vos dons en JUNE
|
||||
|
||||
* [Fred](https://demo.cesium.app/#/app/wot/DsEx1pS33vzYZg4MroyBV9hCw98j1gtHEhwiZ5tK7ech/Fred)
|
||||
Vous avez des questions? Contactez [Fred](mailto:support@qo-op.com)
|
||||
|
||||
|
||||
Des questions? Contactez [support@qo-op.com](mailto:support@qo-op.com)
|
||||
Ce code écrit en bash est un recyclage simplifié de celui utilisé dans [g1sms](https://git.p2p.legal/axiom-team/G1sms)
|
||||
|
||||
---
|
||||
|
||||
# [OpenCollective](https://opencollective.com/monnaie-libre)
|
||||
|
||||
## On compte sur vous.
|
||||
|
||||
[G1SMS](https://g1sms.fr)
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
#!/bin/bash
|
||||
################################################################################
|
||||
# Author: Fred (support@qo-op.com)
|
||||
# Version: 0.1
|
||||
# License: AGPL-3.0 (https://choosealicense.com/licenses/agpl-3.0/)
|
||||
################################################################################
|
||||
MY_PATH="`dirname \"$0\"`" # relative
|
||||
MY_PATH="`( cd \"$MY_PATH\" && pwd )`" # absolutized and normalized
|
||||
ME="${0##*/}"
|
||||
|
||||
[[ -d ~/Bureau ]] && sed "s/_USER_/$USER/g" ${MY_PATH}/g1billet.desktop > ~/Bureau/g1billet.desktop && chmod +x ~/Bureau/g1billet.desktop
|
||||
[[ -d ~/Desktop ]] && sed "s/_USER_/$USER/g" ${MY_PATH}/g1billet.desktop > ~/Desktop/g1billet.desktop && chmod +x ~/Desktop/g1billet.desktop
|
22
crypto.proto
|
@ -1,22 +0,0 @@
|
|||
syntax = "proto2";
|
||||
|
||||
package crypto.pb;
|
||||
|
||||
option go_package = "github.com/libp2p/go-libp2p-core/crypto/pb";
|
||||
|
||||
enum KeyType {
|
||||
RSA = 0;
|
||||
Ed25519 = 1;
|
||||
Secp256k1 = 2;
|
||||
ECDSA = 3;
|
||||
}
|
||||
|
||||
message PublicKey {
|
||||
required KeyType Type = 1;
|
||||
required bytes Data = 2;
|
||||
}
|
||||
|
||||
message PrivateKey {
|
||||
required KeyType Type = 1;
|
||||
required bytes Data = 2;
|
||||
}
|
162
crypto_pb2.py
|
@ -1,162 +0,0 @@
|
|||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# source: crypto.proto
|
||||
|
||||
import sys
|
||||
_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
|
||||
from google.protobuf.internal import enum_type_wrapper
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import message as _message
|
||||
from google.protobuf import reflection as _reflection
|
||||
from google.protobuf import symbol_database as _symbol_database
|
||||
# @@protoc_insertion_point(imports)
|
||||
|
||||
_sym_db = _symbol_database.Default()
|
||||
|
||||
|
||||
|
||||
|
||||
DESCRIPTOR = _descriptor.FileDescriptor(
|
||||
name='crypto.proto',
|
||||
package='crypto.pb',
|
||||
syntax='proto2',
|
||||
serialized_options=_b('Z*github.com/libp2p/go-libp2p-core/crypto/pb'),
|
||||
serialized_pb=_b('\n\x0c\x63rypto.proto\x12\tcrypto.pb\";\n\tPublicKey\x12 \n\x04Type\x18\x01 \x02(\x0e\x32\x12.crypto.pb.KeyType\x12\x0c\n\x04\x44\x61ta\x18\x02 \x02(\x0c\"<\n\nPrivateKey\x12 \n\x04Type\x18\x01 \x02(\x0e\x32\x12.crypto.pb.KeyType\x12\x0c\n\x04\x44\x61ta\x18\x02 \x02(\x0c*9\n\x07KeyType\x12\x07\n\x03RSA\x10\x00\x12\x0b\n\x07\x45\x64\x32\x35\x35\x31\x39\x10\x01\x12\r\n\tSecp256k1\x10\x02\x12\t\n\x05\x45\x43\x44SA\x10\x03\x42,Z*github.com/libp2p/go-libp2p-core/crypto/pb')
|
||||
)
|
||||
|
||||
_KEYTYPE = _descriptor.EnumDescriptor(
|
||||
name='KeyType',
|
||||
full_name='crypto.pb.KeyType',
|
||||
filename=None,
|
||||
file=DESCRIPTOR,
|
||||
values=[
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='RSA', index=0, number=0,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='Ed25519', index=1, number=1,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='Secp256k1', index=2, number=2,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='ECDSA', index=3, number=3,
|
||||
serialized_options=None,
|
||||
type=None),
|
||||
],
|
||||
containing_type=None,
|
||||
serialized_options=None,
|
||||
serialized_start=150,
|
||||
serialized_end=207,
|
||||
)
|
||||
_sym_db.RegisterEnumDescriptor(_KEYTYPE)
|
||||
|
||||
KeyType = enum_type_wrapper.EnumTypeWrapper(_KEYTYPE)
|
||||
RSA = 0
|
||||
Ed25519 = 1
|
||||
Secp256k1 = 2
|
||||
ECDSA = 3
|
||||
|
||||
|
||||
|
||||
_PUBLICKEY = _descriptor.Descriptor(
|
||||
name='PublicKey',
|
||||
full_name='crypto.pb.PublicKey',
|
||||
filename=None,
|
||||
file=DESCRIPTOR,
|
||||
containing_type=None,
|
||||
fields=[
|
||||
_descriptor.FieldDescriptor(
|
||||
name='Type', full_name='crypto.pb.PublicKey.Type', index=0,
|
||||
number=1, type=14, cpp_type=8, label=2,
|
||||
has_default_value=False, default_value=0,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='Data', full_name='crypto.pb.PublicKey.Data', index=1,
|
||||
number=2, type=12, cpp_type=9, label=2,
|
||||
has_default_value=False, default_value=_b(""),
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
],
|
||||
extensions=[
|
||||
],
|
||||
nested_types=[],
|
||||
enum_types=[
|
||||
],
|
||||
serialized_options=None,
|
||||
is_extendable=False,
|
||||
syntax='proto2',
|
||||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=27,
|
||||
serialized_end=86,
|
||||
)
|
||||
|
||||
|
||||
_PRIVATEKEY = _descriptor.Descriptor(
|
||||
name='PrivateKey',
|
||||
full_name='crypto.pb.PrivateKey',
|
||||
filename=None,
|
||||
file=DESCRIPTOR,
|
||||
containing_type=None,
|
||||
fields=[
|
||||
_descriptor.FieldDescriptor(
|
||||
name='Type', full_name='crypto.pb.PrivateKey.Type', index=0,
|
||||
number=1, type=14, cpp_type=8, label=2,
|
||||
has_default_value=False, default_value=0,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='Data', full_name='crypto.pb.PrivateKey.Data', index=1,
|
||||
number=2, type=12, cpp_type=9, label=2,
|
||||
has_default_value=False, default_value=_b(""),
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
],
|
||||
extensions=[
|
||||
],
|
||||
nested_types=[],
|
||||
enum_types=[
|
||||
],
|
||||
serialized_options=None,
|
||||
is_extendable=False,
|
||||
syntax='proto2',
|
||||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=88,
|
||||
serialized_end=148,
|
||||
)
|
||||
|
||||
_PUBLICKEY.fields_by_name['Type'].enum_type = _KEYTYPE
|
||||
_PRIVATEKEY.fields_by_name['Type'].enum_type = _KEYTYPE
|
||||
DESCRIPTOR.message_types_by_name['PublicKey'] = _PUBLICKEY
|
||||
DESCRIPTOR.message_types_by_name['PrivateKey'] = _PRIVATEKEY
|
||||
DESCRIPTOR.enum_types_by_name['KeyType'] = _KEYTYPE
|
||||
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
|
||||
|
||||
PublicKey = _reflection.GeneratedProtocolMessageType('PublicKey', (_message.Message,), dict(
|
||||
DESCRIPTOR = _PUBLICKEY,
|
||||
__module__ = 'crypto_pb2'
|
||||
# @@protoc_insertion_point(class_scope:crypto.pb.PublicKey)
|
||||
))
|
||||
_sym_db.RegisterMessage(PublicKey)
|
||||
|
||||
PrivateKey = _reflection.GeneratedProtocolMessageType('PrivateKey', (_message.Message,), dict(
|
||||
DESCRIPTOR = _PRIVATEKEY,
|
||||
__module__ = 'crypto_pb2'
|
||||
# @@protoc_insertion_point(class_scope:crypto.pb.PrivateKey)
|
||||
))
|
||||
_sym_db.RegisterMessage(PrivateKey)
|
||||
|
||||
|
||||
DESCRIPTOR._options = None
|
||||
# @@protoc_insertion_point(module_scope)
|
|
@ -1,7 +0,0 @@
|
|||
#!/usr/bin/env xdg-open
|
||||
[Desktop Entry]
|
||||
Name=G1BILLET
|
||||
Exec=xdg-open http://localhost:33101
|
||||
Icon=/home/_USER_/.zen/G1BILLET/g1logo.png
|
||||
Type=Application
|
||||
Categories=Utility
|
BIN
g1logo.png
Before Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 147 KiB |
Before Width: | Height: | Size: 33 KiB |
Before Width: | Height: | Size: 97 KiB |
Before Width: | Height: | Size: 825 B |
Before Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 2.4 KiB |
Before Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 116 KiB |
BIN
images/_/g1.png
Before Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 87 KiB |
Before Width: | Height: | Size: 35 KiB |
After Width: | Height: | Size: 120 KiB |
Before Width: | Height: | Size: 104 KiB After Width: | Height: | Size: 104 KiB |
After Width: | Height: | Size: 147 KiB |
After Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 45 KiB |
After Width: | Height: | Size: 76 KiB |
After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 65 KiB |
Before Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 104 KiB |
After Width: | Height: | Size: 77 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 280 KiB |
Before Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 63 KiB |
Before Width: | Height: | Size: 161 KiB |
Before Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 180 KiB |
Before Width: | Height: | Size: 83 KiB |
Before Width: | Height: | Size: 147 KiB |
Before Width: | Height: | Size: 33 KiB |
Before Width: | Height: | Size: 104 KiB |
Before Width: | Height: | Size: 48 KiB |
23
index.php
|
@ -2,29 +2,22 @@
|
|||
$mytime = new Datetime("now");
|
||||
$timestamp = $mytime->format('U').rand();
|
||||
|
||||
/// BROKEN PREFER DAEMON MODE
|
||||
// CREATE 6 G1BILLETS in /tmp/g1billet/$timestamp
|
||||
$page = shell_exec(dirname(__FILE__)."/G1BILLETS.sh '".$_REQUEST['montant']."' '".$timestamp."' '".$_REQUEST['style']."'");
|
||||
|
||||
if ( $_REQUEST['style'] == 'ticket' || $_REQUEST['style'] == 'xbian' || $_REQUEST['style'] == 'astro' ) {
|
||||
$file_type = "jpg";
|
||||
} else {
|
||||
$file_type = "pdf";
|
||||
}
|
||||
$attachment_location = dirname(__FILE__)."/tmp/g1billet/".$timestamp.".".$file_type;
|
||||
|
||||
$attachment_location = "/tmp/g1billet/".$timestamp.".pdf";
|
||||
if (file_exists($attachment_location)) {
|
||||
header($_SERVER["SERVER_PROTOCOL"] . " 200 OK");
|
||||
header($_SERVER["SERVER_PROTOCOL"] . " 200 OK");
|
||||
header("Cache-Control: public"); // needed for internet explorer
|
||||
header("Content-Type: application/".$file_type);
|
||||
header("Content-Type: application/pdf");
|
||||
header("Content-Transfer-Encoding: Binary");
|
||||
header("Content-Length:".filesize($attachment_location));
|
||||
header("Content-Disposition: attachment; filename=".$timestamp.".".$file_type);
|
||||
readfile($attachment_location);
|
||||
unlink(dirname(__FILE__)."/tmp/g1billet/".$timestamp.".".$file_type);
|
||||
die();
|
||||
header("Content-Disposition: attachment; filename=".$timestamp.".pdf");
|
||||
readfile($attachment_location);
|
||||
unlink("/tmp/g1billet/".$timestamp.".pdf");
|
||||
die();
|
||||
} else {
|
||||
die("Error: File not found.".$attachment_location);
|
||||
die("Error: File not found.");
|
||||
}
|
||||
?>
|
||||
|
||||
|
|
35
install.sh
|
@ -1,35 +0,0 @@
|
|||
#!/bin/bash
|
||||
################################################################################
|
||||
# Author: Fred (support@qo-op.com)
|
||||
# Version: 0.1
|
||||
# License: AGPL-3.0 (https://choosealicense.com/licenses/agpl-3.0/)
|
||||
################################################################################
|
||||
MY_PATH="`dirname \"$0\"`" # relative
|
||||
MY_PATH="`( cd \"$MY_PATH\" && pwd )`" # absolutized and normalized
|
||||
ME="${0##*/}"
|
||||
|
||||
echo "#############################################"
|
||||
echo ">>>>>>>>>>> INSTALL CRYPTO AND IMAGING TOOLS "
|
||||
echo "#############################################"
|
||||
sudo apt-get update
|
||||
|
||||
for i in gpg python3 python3-pip imagemagick qrencode ttf-mscorefonts-installer netcat-traditional python3-gpg; do
|
||||
if [ $(dpkg-query -W -f='${Status}' $i 2>/dev/null | grep -c "ok installed") -eq 0 ]; then
|
||||
echo ">>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< Installation $i <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"
|
||||
sudo apt install -y $i
|
||||
[[ $? != 0 ]] && echo "INSTALL $i FAILED." && echo "INSTALL $i FAILED." && continue
|
||||
|
||||
fi
|
||||
done
|
||||
|
||||
for i in pip setuptools wheel cryptography==3.4.8 Ed25519 base58 google duniterpy pynacl pgpy pynentry SecureBytes amzqr; do
|
||||
echo ">>> Installation $i <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"
|
||||
sudo python3 -m pip install -U $i
|
||||
[[ $? != 0 ]] && echo "python3 -m pip install -U $i FAILED." && continue
|
||||
done
|
||||
|
||||
echo "# Correction des droits export PDF imagemagick"
|
||||
if [[ $(cat /etc/ImageMagick-6/policy.xml | grep PDF) ]]; then
|
||||
cat /etc/ImageMagick-6/policy.xml | grep -Ev PDF > /tmp/policy.xml
|
||||
sudo cp /tmp/policy.xml /etc/ImageMagick-6/policy.xml
|
||||
fi
|
896
keygen
|
@ -1,896 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
# link: https://git.p2p.legal/aya/dpgpid/
|
||||
# desc: generate ed25519 keys for duniter and ipfs from gpg
|
||||
|
||||
# Copyleft 2022 Yann Autissier <aya@asycn.io>
|
||||
# all crypto science belongs to Pascal Engélibert <tuxmain@zettascript.org>
|
||||
# coming from files available at https://git.p2p.legal/qo-op/Astroport.ONE/tools
|
||||
# gpgme stuff has been provided by Ben McGinnes
|
||||
# and comes from http://files.au.adversary.org/crypto/gpgme-python-howto.html
|
||||
# gpg key extraction is taken from work of Simon Vareille available at
|
||||
# https://gist.github.com/SimonVareille/fda49baf5f3e15b5c88e25560aeb2822
|
||||
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
import argparse
|
||||
import base58
|
||||
import base64
|
||||
import configparser
|
||||
from cryptography.hazmat.primitives.asymmetric import ed25519
|
||||
from cryptography.hazmat.primitives import serialization
|
||||
import duniterpy.key
|
||||
import gpg
|
||||
from jwcrypto import jwk
|
||||
import logging as log
|
||||
import nacl.bindings
|
||||
import nacl.encoding
|
||||
import pgpy
|
||||
import pynentry
|
||||
from SecureBytes import clearmem
|
||||
import os
|
||||
import re
|
||||
import struct
|
||||
import sys
|
||||
import time
|
||||
import warnings
|
||||
|
||||
__version__='0.0.5'
|
||||
|
||||
class keygen:
|
||||
def __init__(self):
|
||||
self.parser = argparse.ArgumentParser(description="""
|
||||
Generate ed25519 keys for duniter and ipfs from gpg.
|
||||
It converts a gpg key, a duniter username/password, or any ed25519 key to
|
||||
a duniter wallet or an IPFS key.""")
|
||||
self.parser.add_argument(
|
||||
"-d",
|
||||
"--debug",
|
||||
action="store_true",
|
||||
help="show debug informations (WARNING: including SECRET KEY)",
|
||||
)
|
||||
self.parser.add_argument(
|
||||
"-f",
|
||||
"--format",
|
||||
choices=['ewif', 'jwk', 'nacl','pb2','pem','pubsec','seed','wif'],
|
||||
default=None,
|
||||
dest="format",
|
||||
help="output file format, default: pem (pkcs8)",
|
||||
)
|
||||
self.parser.add_argument(
|
||||
"-g",
|
||||
"--gpg",
|
||||
action="store_true",
|
||||
help="use gpg key with uid matched by username",
|
||||
)
|
||||
self.parser.add_argument(
|
||||
"-i",
|
||||
"--input",
|
||||
dest="input",
|
||||
help="read ed25519 key from file FILE, autodetect format: {credentials,ewif,jwk,nacl,mnemonic,pb2,pubsec,seed,wif}",
|
||||
metavar='FILE',
|
||||
)
|
||||
self.parser.add_argument(
|
||||
"-k",
|
||||
"--keys",
|
||||
action="store_true",
|
||||
help="show public and secret keys",
|
||||
)
|
||||
self.parser.add_argument(
|
||||
"-m",
|
||||
"--mnemonic",
|
||||
action="store_true",
|
||||
help="use username as a DUBP mnemonic passphrase",
|
||||
)
|
||||
self.parser.add_argument(
|
||||
"-o",
|
||||
"--output",
|
||||
dest="output",
|
||||
default=None,
|
||||
help="write ed25519 key to file FILE",
|
||||
metavar='FILE',
|
||||
)
|
||||
self.parser.add_argument(
|
||||
"-p",
|
||||
"--prefix",
|
||||
action="store_true",
|
||||
help="prefix output text with key type",
|
||||
)
|
||||
self.parser.add_argument(
|
||||
"-q",
|
||||
"--quiet",
|
||||
action="store_true",
|
||||
help="show only errors",
|
||||
)
|
||||
self.parser.add_argument(
|
||||
"-s",
|
||||
"--secret",
|
||||
action="store_true",
|
||||
help="show only secret key",
|
||||
)
|
||||
self.parser.add_argument(
|
||||
"-t",
|
||||
"--type",
|
||||
choices=['b58mh','b64mh','base58','base64','duniter','ipfs','jwk'],
|
||||
default="base58",
|
||||
dest="type",
|
||||
help="output text format, default: base58",
|
||||
)
|
||||
self.parser.add_argument(
|
||||
"-v",
|
||||
"--verbose",
|
||||
action="store_true",
|
||||
help="show more informations",
|
||||
)
|
||||
self.parser.add_argument(
|
||||
"--version",
|
||||
action="store_true",
|
||||
help="show version and exit",
|
||||
)
|
||||
self.parser.add_argument(
|
||||
'username',
|
||||
nargs="?",
|
||||
)
|
||||
self.parser.add_argument(
|
||||
'password',
|
||||
nargs="?",
|
||||
)
|
||||
|
||||
def _check_args(self, args):
|
||||
log.debug("keygen._check_args(%s)" % args)
|
||||
if self.input is None and self.username is None:
|
||||
self.parser.error('keygen requires an input file or a username')
|
||||
|
||||
def _cleanup(self):
|
||||
log.debug("keygen._cleanup()")
|
||||
if hasattr(self, 'duniterpy'):
|
||||
if hasattr(self.duniterpy, 'seed') and self.duniterpy.seed:
|
||||
clearmem(self.duniterpy.seed)
|
||||
log.debug("cleared: keygen.duniterpy.seed")
|
||||
if hasattr(self.duniterpy, 'sk') and self.duniterpy.sk:
|
||||
clearmem(self.duniterpy.sk)
|
||||
log.debug("cleared: keygen.duniterpy.sk")
|
||||
if hasattr(self, 'ed25519_secret_base58') and self.ed25519_secret_base58:
|
||||
clearmem(self.ed25519_secret_base58)
|
||||
log.debug("cleared: keygen.ed25519_secret_base58")
|
||||
if hasattr(self, 'ed25519_secret_base64') and self.ed25519_secret_base64:
|
||||
clearmem(self.ed25519_secret_base64)
|
||||
log.debug("cleared: keygen.ed25519_secret_base64")
|
||||
if hasattr(self, 'ed25519_secret_bytes') and self.ed25519_secret_bytes:
|
||||
clearmem(self.ed25519_secret_bytes)
|
||||
log.debug("cleared: keygen.ed25519_secret_bytes")
|
||||
if hasattr(self, 'ed25519_secret_pem_pkcs8') and self.ed25519_secret_pem_pkcs8:
|
||||
clearmem(self.ed25519_secret_pem_pkcs8)
|
||||
log.debug("cleared: keygen.ed25515_secret_pem_pkcs8")
|
||||
if hasattr(self, 'ed25519_secret_protobuf') and self.ed25519_secret_protobuf:
|
||||
clearmem(self.ed25519_secret_protobuf)
|
||||
log.debug("cleared: keygen.ed25515_secret_protobuf")
|
||||
if hasattr(self, 'ed25519_seed_bytes') and self.ed25519_seed_bytes:
|
||||
clearmem(self.ed25519_seed_bytes)
|
||||
log.debug("cleared: keygen.ed25519_seed_bytes")
|
||||
if hasattr(self, 'ipfs_privkey') and self.ipfs_privkey:
|
||||
clearmem(self.ipfs_privkey)
|
||||
log.debug("cleared: keygen.ipfs_privkey")
|
||||
if hasattr(self, 'jwk'):
|
||||
if hasattr(self.jwk, 'd') and self.jwk.d:
|
||||
clearmem(self.jwk.d)
|
||||
log.debug("cleared: keygen.jwk.d")
|
||||
if hasattr(self, 'password') and self.password:
|
||||
clearmem(self.password)
|
||||
log.debug("cleared: keygen.password")
|
||||
if hasattr(self, 'pgp_secret_armor') and self.pgp_secret_armor:
|
||||
clearmem(self.pgp_secret_armor)
|
||||
log.debug("cleared: keygen.pgp_secret_armor")
|
||||
if hasattr(self, 'pgpy'):
|
||||
if hasattr(self.pgpy._key.keymaterial, 'p') and self.pgpy._key.keymaterial.p and not isinstance(self.pgpy._key.keymaterial.p, pgpy.packet.fields.ECPoint):
|
||||
clearmem(self.pgpy._key.keymaterial.p)
|
||||
log.debug("cleared: keygen.pgpy._key.material.p")
|
||||
if hasattr(self.pgpy._key.keymaterial, 'q') and self.pgpy._key.keymaterial.q:
|
||||
clearmem(self.pgpy._key.keymaterial.q)
|
||||
log.debug("cleared: keygen.pgpy._key.material.q")
|
||||
if hasattr(self.pgpy._key.keymaterial, 's') and self.pgpy._key.keymaterial.s:
|
||||
clearmem(self.pgpy._key.keymaterial.s)
|
||||
log.debug("cleared: keygen.pgpy._key.material.s")
|
||||
if hasattr(self, 'username') and self.username:
|
||||
clearmem(self.username)
|
||||
log.debug("cleared: keygen.username")
|
||||
|
||||
def _invalid_type(self):
|
||||
log.debug("keygen._invalid_type()")
|
||||
self.parser.error(f"type {self.type} is not valid.")
|
||||
|
||||
def _load_config(self):
|
||||
log.debug("keygen._load_config()")
|
||||
self.config = configparser.RawConfigParser()
|
||||
config_dir = os.path.join(os.environ.get('XDG_CONFIG_HOME', os.path.expanduser('~/.config')), 'dpgpid')
|
||||
log.debug("config_dir=%s" % config_dir)
|
||||
self.config.read( [config_dir + '/keygen.conf'] )
|
||||
|
||||
def _output(self, public_key, secret_key, public_key_prefix, secret_key_prefix):
|
||||
log.debug("keygen._output()")
|
||||
if self.output is None:
|
||||
self._output_text(public_key, secret_key, public_key_prefix, secret_key_prefix)
|
||||
else:
|
||||
self._output_file()
|
||||
os.chmod(self.output, 0o600)
|
||||
self._cleanup()
|
||||
|
||||
def _output_file(self):
|
||||
log.debug("keygen._output_file()")
|
||||
try:
|
||||
if self.format == 'dewif':
|
||||
if not hasattr(self, 'duniterpy'):
|
||||
self.duniterpy_from_ed25519_seed_bytes()
|
||||
if not self.password:
|
||||
with pynentry.PynEntry() as p:
|
||||
p.description = f"""Data in DEWIF file needs to be encrypted.
|
||||
Please enter a password to encrypt seed.
|
||||
"""
|
||||
p.prompt = 'Passphrase:'
|
||||
try:
|
||||
self.password = p.get_pin()
|
||||
except pynentry.PinEntryCancelled:
|
||||
log.warning('Cancelled! Goodbye.')
|
||||
self._cleanup()
|
||||
exit(1)
|
||||
self.duniterpy.save_dewif_v1_file(self.output, self.password)
|
||||
elif self.format == 'ewif':
|
||||
if not hasattr(self, 'duniterpy'):
|
||||
self.duniterpy_from_ed25519_seed_bytes()
|
||||
if not self.password:
|
||||
with pynentry.PynEntry() as p:
|
||||
p.description = f"""Data in EWIF file needs to be encrypted.
|
||||
Please enter a password to encrypt seed.
|
||||
"""
|
||||
p.prompt = 'Passphrase:'
|
||||
try:
|
||||
self.password = p.get_pin()
|
||||
except pynentry.PinEntryCancelled:
|
||||
log.warning('Cancelled! Goodbye.')
|
||||
self._cleanup()
|
||||
exit(1)
|
||||
self.duniterpy.save_ewif_file(self.output, self.password)
|
||||
elif self.format == 'jwk':
|
||||
if not hasattr(self, 'jwk'):
|
||||
self.jwk_from_ed25519()
|
||||
with open(self.output, "w") as file:
|
||||
file.write(self.jwk.export())
|
||||
elif self.format == 'nacl':
|
||||
if not hasattr(self, 'duniterpy'):
|
||||
self.duniterpy_from_ed25519_seed_bytes()
|
||||
self.duniterpy.save_private_key(self.output)
|
||||
elif self.format == 'pb2':
|
||||
if not hasattr(self, 'ed25519_secret_protobuf'):
|
||||
self.protobuf_from_ed25519()
|
||||
with open(self.output, "wb") as file:
|
||||
file.write(self.ed25519_secret_protobuf)
|
||||
elif self.format == 'pubsec':
|
||||
if not hasattr(self, 'duniterpy'):
|
||||
self.duniterpy_from_ed25519_seed_bytes()
|
||||
self.duniterpy.save_pubsec_file(self.output)
|
||||
elif self.format == 'seed':
|
||||
if not hasattr(self, 'duniterpy'):
|
||||
self.duniterpy_from_ed25519_seed_bytes()
|
||||
self.duniterpy.save_seedhex_file(self.output)
|
||||
elif self.format == 'wif':
|
||||
if not hasattr(self, 'duniterpy'):
|
||||
self.duniterpy_from_ed25519_seed_bytes()
|
||||
self.duniterpy.save_wif_file(self.output)
|
||||
else:
|
||||
if not hasattr(self, 'ed25519_secret_pem_pkcs8'):
|
||||
self.pem_pkcs8_from_ed25519()
|
||||
with open(self.output, "w") as file:
|
||||
file.write(self.ed25519_secret_pem_pkcs8)
|
||||
except Exception as e:
|
||||
log.error(f'Unable to output file {self.output}: {e}')
|
||||
self._cleanup()
|
||||
exit(2)
|
||||
|
||||
def _output_text(self, public_key, secret_key, public_key_prefix, secret_key_prefix):
|
||||
log.debug("keygen._output_text()")
|
||||
if self.keys or not self.secret:
|
||||
print("%s" % ''.join([self.prefix * public_key_prefix, public_key]))
|
||||
if self.keys or self.secret:
|
||||
print("%s" % ''.join([self.prefix * secret_key_prefix, secret_key]))
|
||||
|
||||
def _run(self, argv):
|
||||
args = self.parser.parse_args(argv)
|
||||
vars(self).update(vars(args))
|
||||
|
||||
# display version
|
||||
if args.version:
|
||||
version()
|
||||
sys.exit()
|
||||
|
||||
# define log format
|
||||
log_format='%(asctime)s %(levelname)s: %(message)s'
|
||||
log_datefmt='%Y/%m/%d %H:%M:%S'
|
||||
if args.debug:
|
||||
log_level='DEBUG'
|
||||
elif args.quiet:
|
||||
log_level='ERROR'
|
||||
elif args.verbose:
|
||||
log_level='INFO'
|
||||
else:
|
||||
log_level='WARNING'
|
||||
log.basicConfig(format=log_format, datefmt=log_datefmt, level=log_level)
|
||||
log.debug("keygen.run(%s)" % argv)
|
||||
|
||||
self._check_args(args)
|
||||
self._load_config()
|
||||
self.gpg = gpg.Context(armor=True, offline=True)
|
||||
self.gpg.set_passphrase_cb(self.gpg_passphrase_cb)
|
||||
self.ed25519(args)
|
||||
method = getattr(self, f'do_{self.type}', self._invalid_type)
|
||||
return method()
|
||||
|
||||
def b58mh_from_protobuf(self):
|
||||
log.debug("keygen.b58mh_from_protobuf()")
|
||||
try:
|
||||
self.ed25519_public_b58mh = base58.b58encode(self.ed25519_public_protobuf).decode('ascii')
|
||||
self.ed25519_secret_b58mh = base58.b58encode(self.ed25519_secret_protobuf).decode('ascii')
|
||||
except Exception as e:
|
||||
log.error(f'Unable to get b58mh from protobuf: {e}')
|
||||
self._cleanup()
|
||||
exit(2)
|
||||
log.debug("keygen.ed25519_public_b58mh=%s" % self.ed25519_public_b58mh)
|
||||
log.debug("keygen.ed25519_secret_b58mh=%s" % self.ed25519_secret_b58mh)
|
||||
|
||||
def b64mh_from_protobuf(self):
|
||||
log.debug("keygen.b64mh_from_protobuf()")
|
||||
try:
|
||||
self.ed25519_public_b64mh = base64.b64encode(self.ed25519_public_protobuf).decode('ascii')
|
||||
self.ed25519_secret_b64mh = base64.b64encode(self.ed25519_secret_protobuf).decode('ascii')
|
||||
except Exception as e:
|
||||
log.error(f'Unable to get b64mh from protobuf: {e}')
|
||||
self._cleanup()
|
||||
exit(2)
|
||||
log.debug("keygen.ed25519_public_b64mh=%s" % self.ed25519_public_b64mh)
|
||||
log.debug("keygen.ed25519_secret_b64mh=%s" % self.ed25519_secret_b64mh)
|
||||
|
||||
def base58_from_ed25519(self):
|
||||
log.debug("keygen.base58_from_ed25519()")
|
||||
try:
|
||||
self.ed25519_public_base58 = base58.b58encode(self.ed25519_public_bytes).decode('ascii')
|
||||
self.ed25519_secret_base58 = base58.b58encode(self.ed25519_secret_bytes).decode('ascii')
|
||||
except Exception as e:
|
||||
log.error(f'Unable to get base58 from ed25519: {e}')
|
||||
self._cleanup()
|
||||
exit(2)
|
||||
log.debug("keygen.ed25519_public_base58=%s" % self.ed25519_public_base58)
|
||||
log.debug("keygen.ed25519_secret_base58=%s" % self.ed25519_secret_base58)
|
||||
|
||||
def base64_from_ed25519(self):
|
||||
log.debug("keygen.base64_from_ed25519()")
|
||||
try:
|
||||
self.ed25519_public_base64 = base64.b64encode(self.ed25519_public_bytes).decode('ascii')
|
||||
self.ed25519_secret_base64 = base64.b64encode(self.ed25519_secret_bytes).decode('ascii')
|
||||
except Exception as e:
|
||||
log.error(f'Unable to get base64 from ed25519: {e}')
|
||||
self._cleanup()
|
||||
exit(2)
|
||||
log.debug("keygen.ed25519_public_base64=%s" % self.ed25519_public_base64)
|
||||
log.debug("keygen.ed25519_secret_base64=%s" % self.ed25519_secret_base64)
|
||||
|
||||
def do_b58mh(self):
|
||||
log.debug("keygen.do_b58mh()")
|
||||
self.protobuf_from_ed25519()
|
||||
self.b58mh_from_protobuf()
|
||||
self._output(self.ed25519_public_b58mh, self.ed25519_secret_b58mh, 'pub: ', 'sec: ')
|
||||
|
||||
def do_b64mh(self):
|
||||
log.debug("keygen.do_b64mh()")
|
||||
self.protobuf_from_ed25519()
|
||||
self.b64mh_from_protobuf()
|
||||
self._output(self.ed25519_public_b64mh, self.ed25519_secret_b64mh, 'pub: ', 'sec: ')
|
||||
|
||||
def do_base58(self):
|
||||
log.debug("keygen.do_base58()")
|
||||
self.base58_from_ed25519()
|
||||
self._output(self.ed25519_public_base58, self.ed25519_secret_base58, 'pub: ', 'sec: ')
|
||||
|
||||
def do_base64(self):
|
||||
log.debug("keygen.do_base64()")
|
||||
self.base64_from_ed25519()
|
||||
self._output(self.ed25519_public_base64, self.ed25519_secret_base64, 'pub: ', 'sec: ')
|
||||
|
||||
def do_duniter(self):
|
||||
log.debug("keygen.do_duniter()")
|
||||
if not self.format:
|
||||
self.format = 'pubsec'
|
||||
self.base58_from_ed25519()
|
||||
self._output(self.ed25519_public_base58, self.ed25519_secret_base58, 'pub: ', 'sec: ')
|
||||
|
||||
def do_ipfs(self):
|
||||
log.debug("keygen.do_ipfs()")
|
||||
self.protobuf_from_ed25519()
|
||||
self.b58mh_from_protobuf()
|
||||
self.b64mh_from_protobuf()
|
||||
self._output(self.ed25519_public_b58mh, self.ed25519_secret_b64mh, 'PeerID: ', 'PrivKEY: ')
|
||||
|
||||
def do_jwk(self):
|
||||
log.debug("keygen.do_jwk()")
|
||||
self.jwk_from_ed25519()
|
||||
self._output(self.jwk.export_public(), self.jwk.export_private(), 'pub: ', 'sec: ')
|
||||
|
||||
def duniterpy_from_credentials(self):
|
||||
log.debug("keygen.duniterpy_from_credentials()")
|
||||
try:
|
||||
scrypt_params = duniterpy.key.scrypt_params.ScryptParams(
|
||||
int(self.config.get('scrypt', 'n')) if self.config.has_option('scrypt', 'n') else 4096,
|
||||
int(self.config.get('scrypt', 'r')) if self.config.has_option('scrypt', 'r') else 16,
|
||||
int(self.config.get('scrypt', 'p')) if self.config.has_option('scrypt', 'p') else 1,
|
||||
int(self.config.get('scrypt', 'sl')) if self.config.has_option('scrypt', 'sl') else 32,
|
||||
)
|
||||
if not self.password:
|
||||
with pynentry.PynEntry() as p:
|
||||
p.description = f"""Please enter the passord for username "{self.username}"."""
|
||||
p.prompt = 'Passsord:'
|
||||
try:
|
||||
self.password = p.get_pin()
|
||||
except pynentry.PinEntryCancelled:
|
||||
log.warning('Cancelled! Goodbye.')
|
||||
self._cleanup()
|
||||
exit(1)
|
||||
self.duniterpy = duniterpy.key.SigningKey.from_credentials(
|
||||
self.username,
|
||||
self.password,
|
||||
scrypt_params
|
||||
)
|
||||
except Exception as e:
|
||||
log.error(f'Unable to get duniter from credentials: {e}')
|
||||
self._cleanup()
|
||||
exit(2)
|
||||
log.debug("keygen.duniterpy.seed: %s" % self.duniterpy.seed)
|
||||
|
||||
def duniterpy_from_ed25519_seed_bytes(self):
|
||||
log.debug("keygen.duniterpy_from_ed25519_seed_bytes()")
|
||||
try:
|
||||
self.duniterpy = duniterpy.key.SigningKey(self.ed25519_seed_bytes)
|
||||
except Exception as e:
|
||||
log.error(f'Unable to get duniterpy from ed25519 seed bytes: {e}')
|
||||
self._cleanup()
|
||||
exit(2)
|
||||
log.debug("keygen.duniterpy.seed: %s" % self.duniterpy.seed)
|
||||
|
||||
def duniterpy_from_file(self):
|
||||
log.debug("keygen.duniterpy_from_file()")
|
||||
try:
|
||||
with open(self.input, 'r') as file:
|
||||
lines = file.readlines()
|
||||
if len(lines) > 0:
|
||||
line = lines[0].strip()
|
||||
regex_ewif = re.compile('^Type: EWIF$')
|
||||
regex_jwk = re.compile('^\\s*{\\s*"crv":\\s*"Ed25519",\\s*"d":\\s*"(.)+",\\s*"kty":\\s*"OKP",\\s*"x":\\s*"(.)+"\\s*}')
|
||||
regex_nacl = re.compile('^\\s*{\\s*"priv":\\s*"[0-9a-fA-F]+",\\s*"verify":\\s*"[0-9a-fA-F]+",\\s*"sign":\\s*"[0-9a-fA-F]+"\\s*}')
|
||||
regex_pem = re.compile('^-----BEGIN PRIVATE KEY-----$')
|
||||
regex_pubsec = re.compile('^Type: PubSec$')
|
||||
regex_seed = re.compile('^[0-9a-fA-F]{64}$')
|
||||
regex_ssb = re.compile('\\s*{\\s*"curve":\\s*"ed25519",\\s*"public":\\s*"(.+)\\.ed25519",\\s*"private":\\s*"(.+)\\.ed25519",\\s*"id":\\s*"@(.+).ed25519"\\s*}')
|
||||
regex_wif = re.compile('^Type: WIF$')
|
||||
if re.search(regex_ewif, line):
|
||||
log.info("input file format detected: ewif")
|
||||
if not self.password:
|
||||
with pynentry.PynEntry() as p:
|
||||
p.description = f"""Data in EWIF file is encrypted.
|
||||
Please enter a password to decrypt seed.
|
||||
"""
|
||||
p.prompt = 'Passphrase:'
|
||||
try:
|
||||
self.password = p.get_pin()
|
||||
except pynentry.PinEntryCancelled:
|
||||
log.warning('Cancelled! Goodbye.')
|
||||
self._cleanup()
|
||||
exit(1)
|
||||
self.duniterpy = duniterpy.key.SigningKey.from_ewif_file(self.input, self.password)
|
||||
elif re.search(regex_jwk, line):
|
||||
log.info("input file format detected: jwk")
|
||||
self.jwk_from_json(line)
|
||||
self.ed25519_seed_bytes_from_jwk()
|
||||
self.duniterpy_from_ed25519_seed_bytes()
|
||||
elif re.search(regex_nacl, line):
|
||||
log.info("input file format detected: nacl")
|
||||
self.duniterpy = duniterpy.key.SigningKey.from_private_key(self.input)
|
||||
elif re.search(regex_pem, line):
|
||||
log.info("input file format detected: pem")
|
||||
self.ed25519_seed_bytes_from_pem(''.join(lines).encode())
|
||||
self.duniterpy_from_ed25519_seed_bytes()
|
||||
elif re.search(regex_pubsec, line):
|
||||
log.info("input file format detected: pubsec")
|
||||
self.duniterpy = duniterpy.key.SigningKey.from_pubsec_file(self.input)
|
||||
elif re.search(regex_seed, line):
|
||||
log.info("input file format detected: seed")
|
||||
self.duniterpy = duniterpy.key.SigningKey.from_seedhex_file(self.input)
|
||||
elif re.search(regex_ssb, line):
|
||||
log.info("input file format detected: ssb")
|
||||
self.duniterpy = duniterpy.key.SigningKey.from_ssb_file(self.input)
|
||||
elif re.search(regex_wif, line):
|
||||
log.info("input file format detected: wif")
|
||||
self.duniterpy = duniterpy.key.SigningKey.from_wif_file(self.input)
|
||||
elif len(line.split(' ')) == 12:
|
||||
log.info("input file format detected: mnemonic")
|
||||
self.username = line
|
||||
self.duniterpy_from_mnemonic()
|
||||
elif len(lines) > 1:
|
||||
log.info("input file format detected: credentials")
|
||||
self.username = line
|
||||
self.password = lines[1].strip()
|
||||
self.duniterpy_from_credentials()
|
||||
else:
|
||||
raise NotImplementedError('unknown input file format.')
|
||||
else:
|
||||
raise NotImplementedError('empty file.')
|
||||
except UnicodeDecodeError as e:
|
||||
try:
|
||||
with open(self.input, 'rb') as file:
|
||||
lines = file.readlines()
|
||||
if len(lines) > 0:
|
||||
line = lines[0].strip()
|
||||
regex_dewif = re.compile(b'^\x00\x00\x00\x01\x00\x00\x00\x01')
|
||||
regex_pb2 = re.compile(b'^\x08\x01\x12@')
|
||||
if re.search(regex_dewif, line):
|
||||
log.info("input file format detected: dewif")
|
||||
if not self.password:
|
||||
with pynentry.PynEntry() as p:
|
||||
p.description = f"""Data in DEWIF file is encrypted.
|
||||
Please enter a password to decrypt seed.
|
||||
"""
|
||||
p.prompt = 'Passphrase:'
|
||||
try:
|
||||
self.password = p.get_pin()
|
||||
except pynentry.PinEntryCancelled:
|
||||
log.warning('Cancelled! Goodbye.')
|
||||
self._cleanup()
|
||||
exit(1)
|
||||
self.duniterpy = duniterpy.key.SigningKey.from_dewif_file(self.input, self.password)
|
||||
if re.search(regex_pb2, line):
|
||||
log.info("input file format detected: pb2")
|
||||
self.ed25519_secret_protobuf = line
|
||||
self.ed25519_seed_bytes_from_protobuf()
|
||||
self.duniterpy_from_ed25519_seed_bytes()
|
||||
else:
|
||||
raise NotImplementedError('unknown input file format.')
|
||||
else:
|
||||
raise NotImplementedError('empty file.')
|
||||
except Exception as e:
|
||||
log.error(f'Unable to get duniterpy from file {self.input}: {e}')
|
||||
self._cleanup()
|
||||
exit(2)
|
||||
except Exception as e:
|
||||
log.error(f'Unable to get duniterpy from file {self.input}: {e}')
|
||||
self._cleanup()
|
||||
exit(2)
|
||||
log.debug("keygen.duniterpy.seed: %s" % self.duniterpy.seed)
|
||||
|
||||
def duniterpy_from_mnemonic(self):
|
||||
log.debug("keygen.duniterpy_from_mnemonic()")
|
||||
try:
|
||||
scrypt_params = duniterpy.key.scrypt_params.ScryptParams(
|
||||
int(self.config.get('scrypt', 'n')) if self.config.has_option('scrypt', 'n') else 4096,
|
||||
int(self.config.get('scrypt', 'r')) if self.config.has_option('scrypt', 'r') else 16,
|
||||
int(self.config.get('scrypt', 'p')) if self.config.has_option('scrypt', 'p') else 1,
|
||||
int(self.config.get('scrypt', 'sl')) if self.config.has_option('scrypt', 'sl') else 32,
|
||||
)
|
||||
self.duniterpy = duniterpy.key.SigningKey.from_dubp_mnemonic(
|
||||
self.username,
|
||||
scrypt_params
|
||||
)
|
||||
except Exception as e:
|
||||
log.error(f'Unable to get duniterpy from mnemonic: {e}')
|
||||
self._cleanup()
|
||||
exit(2)
|
||||
log.debug("keygen.duniterpy.seed: %s" % self.duniterpy.seed)
|
||||
|
||||
def ed25519(self, args):
|
||||
log.debug("keygen.ed25519(%s)" % args)
|
||||
if args.gpg:
|
||||
self.ed25519_from_gpg()
|
||||
else:
|
||||
if self.input:
|
||||
self.duniterpy_from_file()
|
||||
else:
|
||||
if self.mnemonic:
|
||||
self.duniterpy_from_mnemonic()
|
||||
else:
|
||||
self.duniterpy_from_credentials()
|
||||
self.ed25519_from_duniterpy()
|
||||
|
||||
def ed25519_from_duniterpy(self):
|
||||
log.debug("keygen.ed25519_from_duniterpy()")
|
||||
try:
|
||||
self.ed25519_seed_bytes_from_duniterpy()
|
||||
self.ed25519_from_seed_bytes()
|
||||
except:
|
||||
log.error(f'Unable to get ed25519 from duniterpy: {e}')
|
||||
self._cleanup()
|
||||
exit(2)
|
||||
|
||||
def ed25519_from_gpg(self):
|
||||
log.debug("keygen.ed25519_from_gpg()")
|
||||
try:
|
||||
self.pgpy_from_gpg()
|
||||
self.ed25519_from_pgpy()
|
||||
except Exception as e:
|
||||
log.error(f'Unable to get ed25519 from pgp: {e}')
|
||||
self._cleanup()
|
||||
exit(2)
|
||||
|
||||
def ed25519_from_pgpy(self):
|
||||
log.debug("keygen.ed25519_from_pgpy()")
|
||||
try:
|
||||
log.debug("keygen.pgpy.fingerprint.keyid=%s" % self.pgpy.fingerprint.keyid)
|
||||
log.debug("keygen.pgpy.is_protected=%s" % self.pgpy.is_protected)
|
||||
if self.pgpy.is_protected:
|
||||
if not self.password:
|
||||
with pynentry.PynEntry() as p:
|
||||
p.description = f"""The exported pgp key id "{self.pgpy.fingerprint.keyid}" of user "{self.username}" is password protected.
|
||||
Please enter the passphrase again to unlock it.
|
||||
"""
|
||||
p.prompt = 'Passphrase:'
|
||||
try:
|
||||
self.password = p.get_pin()
|
||||
except pynentry.PinEntryCancelled:
|
||||
log.warning('Cancelled! Goodbye.')
|
||||
self._cleanup()
|
||||
exit(1)
|
||||
try:
|
||||
with warnings.catch_warnings():
|
||||
# remove CryptographyDeprecationWarning about deprecated
|
||||
# SymmetricKeyAlgorithm IDEA, CAST5 and Blowfish (PGPy v0.5.4)
|
||||
warnings.simplefilter('ignore')
|
||||
with self.pgpy.unlock(self.password):
|
||||
assert self.pgpy.is_unlocked
|
||||
log.debug("keygen.pgpy.is_unlocked=%s" % self.pgpy.is_unlocked)
|
||||
self.ed25519_seed_bytes_from_pgpy()
|
||||
except Exception as e:
|
||||
log.error(f"""Unable to unlock pgp secret key id "{self.pgpy.fingerprint.keyid}" of user "{self.username}": {e}""")
|
||||
self._cleanup()
|
||||
exit(2)
|
||||
else:
|
||||
self.ed25519_seed_bytes_from_pgpy()
|
||||
self.ed25519_from_seed_bytes()
|
||||
except Exception as e:
|
||||
log.error(f'Unable to get ed25519 seed bytes from pgpy: {e}')
|
||||
self._cleanup()
|
||||
exit(2)
|
||||
|
||||
def ed25519_from_seed_bytes(self):
|
||||
log.debug("keygen.ed25519_from_seed_bytes()")
|
||||
try:
|
||||
self.ed25519_public_bytes, self.ed25519_secret_bytes = nacl.bindings.crypto_sign_seed_keypair(self.ed25519_seed_bytes)
|
||||
self.ed25519 = ed25519.Ed25519PrivateKey.from_private_bytes(self.ed25519_seed_bytes)
|
||||
except Exception as e:
|
||||
log.error(f'Unable to get ed25519 from seed bytes: {e}')
|
||||
self._cleanup()
|
||||
exit(2)
|
||||
log.debug("keygen.ed25519_public_bytes=%s" % self.ed25519_public_bytes)
|
||||
log.debug("keygen.ed25519_secret_bytes=%s" % self.ed25519_secret_bytes)
|
||||
|
||||
def ed25519_seed_bytes_from_duniterpy(self):
|
||||
log.debug("keygen.ed25519_seed_bytes_from_duniterpy()")
|
||||
try:
|
||||
self.ed25519_seed_bytes = self.duniterpy.sk[:32]
|
||||
except Exception as e:
|
||||
log.error(f'Unable to get ed25519 seed bytes from duniterpy: {e}')
|
||||
self._cleanup()
|
||||
exit(2)
|
||||
log.debug("keygen.ed25519_seed_bytes=%s" % self.ed25519_seed_bytes)
|
||||
|
||||
def ed25519_seed_bytes_from_jwk(self):
|
||||
log.debug("keygen.ed25519_seed_bytes_from_jwk()")
|
||||
try:
|
||||
self.ed25519_seed_bytes = self.jwk._okp_pri().private_bytes(encoding=serialization.Encoding.Raw, format=serialization.PrivateFormat.Raw, encryption_algorithm=serialization.NoEncryption())
|
||||
except Exception as e:
|
||||
log.error(f'Unable to get ed25519 seed bytes from jwk: {e}')
|
||||
self._cleanup()
|
||||
exit(2)
|
||||
|
||||
def ed25519_seed_bytes_from_pem(self, pem):
|
||||
log.debug("keygen.ed25519_seed_bytes_from_pem()")
|
||||
try:
|
||||
self.ed25519_seed_bytes = serialization.load_pem_private_key(pem, password=None).private_bytes(encoding=serialization.Encoding.Raw, format=serialization.PrivateFormat.Raw, encryption_algorithm=serialization.NoEncryption())
|
||||
except Exception as e:
|
||||
log.error(f'Unable to get ed25519 seed bytes from pem: {e}')
|
||||
self._cleanup()
|
||||
exit(2)
|
||||
|
||||
def ed25519_seed_bytes_from_pgpy(self):
|
||||
log.debug("keygen.ed25519_seed_bytes_from_pgpy()")
|
||||
try:
|
||||
self.pgpy_key_type()
|
||||
if self.pgpy_key_type == 'RSA':
|
||||
log.debug("keygen.pgpy._key.keymaterial.p=%s" % self.pgpy._key.keymaterial.p)
|
||||
log.debug("keygen.pgpy._key.keymaterial.q=%s" % self.pgpy._key.keymaterial.q)
|
||||
# custom seed: use sha256 hash of (p + q)
|
||||
self.ed25519_seed_bytes = nacl.bindings.crypto_hash_sha256(long_to_bytes(self.pgpy._key.keymaterial.p + self.pgpy._key.keymaterial.q))
|
||||
elif self.pgpy_key_type in ('ECDSA', 'EdDSA', 'ECDH'):
|
||||
log.debug("keygen.pgpy._key.keymaterial.s=%s" % self.pgpy._key.keymaterial.s)
|
||||
self.ed25519_seed_bytes = long_to_bytes(self.pgpy._key.keymaterial.s)
|
||||
else:
|
||||
raise NotImplementedError(f"getting seed from {self.pgpy_key_type} key is not implemented")
|
||||
except Exception as e:
|
||||
log.error(f'Unable to get ed25519 seed bytes from pgpy: {e}')
|
||||
self._cleanup()
|
||||
exit(2)
|
||||
log.debug("keygen.ed25519_seed_bytes=%s" % self.ed25519_seed_bytes)
|
||||
|
||||
def ed25519_seed_bytes_from_protobuf(self):
|
||||
log.debug("keygen.ed25519_seed_bytes_from_protobuf()")
|
||||
try:
|
||||
self.ed25519_seed_bytes = self.ed25519_secret_protobuf.lstrip(b'\x08\x01\x12@')[:32]
|
||||
except Exception as e:
|
||||
log.error(f'Unable to get ed25519 seed bytes from protobuf: {e}')
|
||||
self._cleanup()
|
||||
exit(2)
|
||||
log.debug("keygen.ed25519_seed_bytes=%s" % self.ed25519_seed_bytes)
|
||||
|
||||
def gpg_passphrase_cb(self, uid_hint, passphrase_info, prev_was_bad):
|
||||
log.debug("keygen.gpg_passphrase_cb(%s, %s, %s)" % (uid_hint, passphrase_info, prev_was_bad))
|
||||
return self.password
|
||||
|
||||
def jwk_from_ed25519(self):
|
||||
log.debug("keygen.jwk_from_ed25519()")
|
||||
try:
|
||||
self.jwk = jwk.JWK.from_pyca(self.ed25519)
|
||||
except Exception as e:
|
||||
log.error(f'Unable to get jwk from ed25519: {e}')
|
||||
self._cleanup()
|
||||
exit(2)
|
||||
|
||||
def jwk_from_json(self, json):
|
||||
log.debug("keygen.jwk_from_json()")
|
||||
try:
|
||||
self.jwk = jwk.JWK.from_json(json)
|
||||
except Exception as e:
|
||||
log.error(f'Unable to get jwk from json: {e}')
|
||||
self._cleanup()
|
||||
exit(2)
|
||||
|
||||
def pem_pkcs8_from_ed25519(self):
|
||||
log.debug("keygen.pem_pkcs8_from_ed25519()")
|
||||
try:
|
||||
self.ed25519_secret_pem_pkcs8 = self.ed25519.private_bytes(encoding=serialization.Encoding.PEM, format=serialization.PrivateFormat.PKCS8, encryption_algorithm=serialization.NoEncryption()).decode('ascii')
|
||||
except Exception as e:
|
||||
log.error(f'Unable to get pem pkcs8 from ed25519: {e}')
|
||||
self._cleanup()
|
||||
exit(2)
|
||||
log.debug("keygen.ed25519_secret_pem_pkcs8=%s" % self.ed25519_secret_pem_pkcs8)
|
||||
|
||||
def pgpy_from_gpg(self):
|
||||
log.debug("keygen.pgpy_from_gpg()")
|
||||
try:
|
||||
self.gpg_seckeys = list(self.gpg.keylist(pattern=self.username, secret=True))
|
||||
log.debug("keygen.gpg_seckeys=%s" % self.gpg_seckeys)
|
||||
if not self.gpg_seckeys:
|
||||
log.warning(f"""Unable to find any key matching username "{self.username}".""")
|
||||
self._cleanup()
|
||||
exit(1)
|
||||
else:
|
||||
self.gpg_seckey = self.gpg_seckeys[0]
|
||||
log.info(f"""Found key id "{self.gpg_seckey.fpr}" matching username "{self.username}".""")
|
||||
log.debug("keygen.gpg_seckey.expired=%s" % self.gpg_seckey.expired)
|
||||
log.debug("keygen.gpg_seckey.fpr=%s" % self.gpg_seckey.fpr)
|
||||
log.debug("keygen.gpg_seckey.revoked=%s" % self.gpg_seckey.revoked)
|
||||
log.debug("keygen.gpg_seckey.uids=%s" % self.gpg_seckey.uids)
|
||||
log.debug("keygen.gpg_seckey.owner_trust=%s" % self.gpg_seckey.owner_trust)
|
||||
log.debug("keygen.gpg_seckey.last_update=%s" % self.gpg_seckey.last_update)
|
||||
if self.password:
|
||||
self.gpg.set_pinentry_mode(gpg.constants.PINENTRY_MODE_LOOPBACK)
|
||||
self.pgp_public_armor = self.gpg.key_export(self.gpg_seckey.fpr)
|
||||
self.pgp_secret_armor = self.gpg.key_export_secret(self.gpg_seckey.fpr)
|
||||
log.debug("keygen.pgp_secret_armor=%s" % self.pgp_secret_armor)
|
||||
if not self.pgp_secret_armor:
|
||||
log.error(f"""Unable to export gpg secret key id "{self.gpg_seckey.fpr}" of user "{self.username}". Please check your password!""")
|
||||
self._cleanup()
|
||||
exit(2)
|
||||
with warnings.catch_warnings():
|
||||
# remove CryptographyDeprecationWarning about deprecated
|
||||
# SymmetricKeyAlgorithm IDEA, CAST5 and Blowfish (PGPy v0.5.4)
|
||||
warnings.simplefilter('ignore')
|
||||
self.pgpy, _ = pgpy.PGPKey.from_blob(self.pgp_secret_armor)
|
||||
except Exception as e:
|
||||
log.error(f'Unable to get pgpy from gpg: {e}')
|
||||
self._cleanup()
|
||||
exit(2)
|
||||
|
||||
def pgpy_key_type(self):
|
||||
log.debug("keygen.pgpy_key_type()")
|
||||
if isinstance(self.pgpy._key.keymaterial, pgpy.packet.fields.RSAPriv):
|
||||
self.pgpy_key_type = 'RSA'
|
||||
elif isinstance(self.pgpy._key.keymaterial, pgpy.packet.fields.DSAPriv):
|
||||
self.pgpy_key_type = 'DSA'
|
||||
elif isinstance(self.pgpy._key.keymaterial, pgpy.packet.fields.ElGPriv):
|
||||
self.pgpy_key_type = 'ElGamal'
|
||||
elif isinstance(self.pgpy._key.keymaterial, pgpy.packet.fields.ECDSAPriv):
|
||||
self.pgpy_key_type = 'ECDSA'
|
||||
elif isinstance(self.pgpy._key.keymaterial, pgpy.packet.fields.EdDSAPriv):
|
||||
self.pgpy_key_type = 'EdDSA'
|
||||
elif isinstance(self.pgpy._key.keymaterial, pgpy.packet.fields.ECDHPriv):
|
||||
self.pgpy_key_type = 'ECDH'
|
||||
else:
|
||||
self.pgpy_key_type = 'undefined'
|
||||
log.debug("keygen.pgpy_key_type=%s" % self.pgpy_key_type)
|
||||
|
||||
def protobuf_from_ed25519(self):
|
||||
# libp2p protobuf version 2
|
||||
log.debug("keygen.protobuf_from_ed25519()")
|
||||
try:
|
||||
self.ed25519_public_protobuf = b'\x00$\x08\x01\x12 ' + self.ed25519_public_bytes
|
||||
self.ed25519_secret_protobuf = b'\x08\x01\x12@' + self.ed25519_secret_bytes
|
||||
except Exception as e:
|
||||
log.error(f'Unable to get protobuf from ed25519: {e}')
|
||||
self._cleanup()
|
||||
exit(2)
|
||||
log.debug("keygen.ed25519_public_protobuf=%s" % self.ed25519_public_protobuf)
|
||||
log.debug("keygen.ed25519_secret_protobuf=%s" % self.ed25519_secret_protobuf)
|
||||
|
||||
##
|
||||
# long_to_bytes comes from PyCrypto, which is released into Public Domain
|
||||
# https://github.com/dlitz/pycrypto/blob/master/lib/Crypto/Util/number.py
|
||||
def bytes_to_long(s):
|
||||
"""bytes_to_long(string) : long
|
||||
Convert a byte string to a long integer.
|
||||
This is (essentially) the inverse of long_to_bytes().
|
||||
"""
|
||||
acc = 0
|
||||
unpack = struct.unpack
|
||||
length = len(s)
|
||||
if length % 4:
|
||||
extra = (4 - length % 4)
|
||||
s = b'\000' * extra + s
|
||||
length = length + extra
|
||||
for i in range(0, length, 4):
|
||||
acc = (acc << 32) + unpack('>I', s[i:i+4])[0]
|
||||
return acc
|
||||
|
||||
def long_to_bytes(n, blocksize=0):
|
||||
"""long_to_bytes(n:long, blocksize:int) : string
|
||||
Convert a long integer to a byte string.
|
||||
If optional blocksize is given and greater than zero, pad the front of the
|
||||
byte string with binary zeros so that the length is a multiple of
|
||||
blocksize.
|
||||
"""
|
||||
# after much testing, this algorithm was deemed to be the fastest
|
||||
s = b''
|
||||
n = int(n)
|
||||
pack = struct.pack
|
||||
while n > 0:
|
||||
s = pack('>I', n & 0xffffffff) + s
|
||||
n = n >> 32
|
||||
# strip off leading zeros
|
||||
for i in range(len(s)):
|
||||
if s[i] != b'\000'[0]:
|
||||
break
|
||||
else:
|
||||
# only happens when n == 0
|
||||
s = b'\000'
|
||||
i = 0
|
||||
s = s[i:]
|
||||
# add back some pad bytes. this could be done more efficiently w.r.t. the
|
||||
# de-padding being done above, but sigh...
|
||||
if blocksize > 0 and len(s) % blocksize:
|
||||
s = (blocksize - len(s) % blocksize) * b'\000' + s
|
||||
return s
|
||||
|
||||
def main(argv=None):
|
||||
if argv is None:
|
||||
argv = sys.argv[1:]
|
||||
|
||||
cli = keygen()
|
||||
return cli._run(argv)
|
||||
|
||||
def version(version=__version__):
|
||||
print("%s v%s" % (sys.argv[0],version))
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
16
search
|
@ -1,16 +0,0 @@
|
|||
#!/bin/bash
|
||||
clear
|
||||
echo "------------------------------------------------------------------------------"
|
||||
if [ "$1" == "" ]; then
|
||||
echo " Nothing to search for!"
|
||||
else
|
||||
echo " Searching for "$1" recursively. Please Wait..."
|
||||
echo "------------------------------------------------------------------------------"
|
||||
grep -h -r --exclude=B00 -H --colour=always "$1" ./
|
||||
fi
|
||||
echo "------------------------------------------------------------------------------"
|
||||
if [ "$2" != "" ]; then
|
||||
echo " To replace \"$1\" whith \"$2\", please run"
|
||||
echo " grep -rl '$1' ./ | xargs sed -i 's~$1~$2~g'"
|
||||
fi
|
||||
## THIS IS A GREAT RETRO ENGINEERING AND CODING TOOLS
|
|
@ -1,40 +0,0 @@
|
|||
#!/bin/bash
|
||||
################################################################################
|
||||
# Author: Fred (support@qo-op.com)
|
||||
# Version: 0.1
|
||||
# License: AGPL-3.0 (https://choosealicense.com/licenses/agpl-3.0/)
|
||||
################################################################################
|
||||
MY_PATH="`dirname \"$0\"`" # relative
|
||||
MY_PATH="`( cd \"$MY_PATH\" && pwd )`" # absolutized and normalized
|
||||
ME="${0##*/}"
|
||||
|
||||
echo "#############################################"
|
||||
echo ">>>>>>>>>>> SYSTEMD SETUP "
|
||||
echo "#############################################"
|
||||
|
||||
echo "CREATE SYSTEMD g1billet SERVICE >>>>>>>>>>>>>>>>>>"
|
||||
cat > /tmp/g1billet.service <<EOF
|
||||
[Unit]
|
||||
Description=G1BILLET API
|
||||
After=network.target
|
||||
Requires=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=_USER_
|
||||
RestartSec=1
|
||||
Restart=always
|
||||
ExecStart=_MYPATH_/G1BILLETS.sh daemon
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
sudo cp -f /tmp/g1billet.service /etc/systemd/system/
|
||||
sudo sed -i "s~_USER_~${USER}~g" /etc/systemd/system/g1billet.service
|
||||
sudo sed -i "s~_MYPATH_~${MY_PATH}~g" /etc/systemd/system/g1billet.service
|
||||
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable g1billet
|
||||
sudo systemctl restart g1billet
|
||||
|
Before Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 7.8 KiB |
Before Width: | Height: | Size: 104 KiB |
Before Width: | Height: | Size: 65 KiB |
Before Width: | Height: | Size: 68 KiB |
Before Width: | Height: | Size: 161 KiB |
Before Width: | Height: | Size: 147 KiB |
Before Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 39 KiB |
Before Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 97 KiB |
Before Width: | Height: | Size: 175 KiB |