Compare commits

...

145 Commits

Author SHA1 Message Date
fred 87904551fb G1BILLET révolutionne le "BILLET" tel que nous le connaissons... 2024-02-11 14:59:06 +01:00
fred f949822148 ZenCard "avec dedicace" 2024-02-11 14:52:55 +01:00
fred 9f225413db ZenCard ready 2024-02-11 14:50:45 +01:00
fred 3d908591fa G1 NOTERIB 2024-02-02 19:32:18 +01:00
fred b3b19a6eec to find amzqr export PATH="$HOME/.local/bin:$PATH" 2024-01-11 16:20:17 +01:00
fred a3df26659d amzqr missing fall back to qrencode 2024-01-11 16:18:48 +01:00
fred 17b06fe84d correct 6 per page G1BILLET mode 2024-01-06 19:49:09 +01:00
fred 0cdf22c4e0 small fix 2023-12-17 18:53:25 +01:00
fred 48cf86356a https://opencollective.com/made-in-zen 2023-12-06 23:06:31 +01:00
fred 82dea01a72 bug with killing old 33102 2023-12-06 21:38:26 +01:00
fred 8b38684668 Ẑen UPlanet stage 2023-11-24 03:44:01 +01:00
fred 84247d419e some twerks 2023-11-17 03:37:05 +01:00
fred a107610128 echo not cat 2023-11-06 22:02:24 +01:00
fred f3971086bc kill old 33102 2023-10-26 14:37:26 +02:00
fred 990318b2e3 Get PLAYER "Dessin de MOA" as G1BILLET backgroud image 2023-10-26 00:56:59 +02:00
fred 75e131a593 ASTROLINK="https://ipfs.asycn.io/ipns/${ASTRONS}" 2023-10-09 17:51:31 +02:00
fred 3766823b7c G1CARD 2023-09-22 16:44:06 +02:00
fred a7cc30d4ca greener 2023-09-04 15:41:59 +02:00
fred cda7bd2364 Go GREEN 2023-09-04 15:37:00 +02:00
fred 95dc431b45 G1CARD 2023-07-03 03:05:50 +02:00
fred da4ac326a8 Web QR 2023-06-30 03:46:20 +02:00
fred 946408ee3a https://opencollective.com/monnaie-libre 2023-06-09 10:48:34 +02:00
fred e3fd1d2a20 ♥Box network ready 2023-05-30 18:59:39 +02:00
fred e9a0efb7ad indicate 33102 https proxy url path 2023-05-30 18:53:18 +02:00
fred ca41a2ddbf indicate 33102 https proxy url path 2023-05-30 18:52:53 +02:00
fred 9cad898388 write your nginxproxymanager to 33102 port in ~/.zen/♥Box file (ie https://out.domain.tld ) 2023-05-30 18:46:26 +02:00
fred a12633262f G1BILLET v 1.0 2023-05-17 16:23:09 +02:00
fred ee32f3718a images de fond pour QRCODE 2023-05-13 13:59:25 +02:00
fred 3c87bf3c02 DOC link 2023-05-12 21:52:22 +02:00
fred b6daea1669 push 2023-05-11 17:24:46 +02:00
fred abbc1bbe15 G1BILLET v2.rc1 2023-05-07 03:03:11 +02:00
fred b9db92a90c f 2023-05-06 04:14:07 +02:00
fred 5a9cf7706a Box 2023-05-06 04:07:34 +02:00
fred 6323455a1a ♥BOX compatible 2023-05-06 04:01:53 +02:00
fred e20f719d1f G1BILLET+ & G1PASS & G1PASS+ 2023-05-06 02:55:19 +02:00
fred fb5083ab42 add desktop shortcut 2023-05-03 02:46:00 +02:00
fred ee83196c16 v10.01 2023-05-02 02:45:52 +02:00
fred ac2c6688c8 G1BILLET v1.0 2023-05-01 21:34:42 +02:00
fred 38ecf06a34 Activate own styles in "./_images/_" 2023-04-21 18:18:00 +02:00
fred 482275faf2 ⚠️ **Pour utiliser G1PASS : Installez [Astroport.ONE](https://git.p2p.legal/STI/Astroport.ONE).** 2023-04-20 23:25:04 +02:00
fred 3e76bb7ee3 /qo-op/G1BILLET/issues 2023-04-20 22:56:53 +02:00
fred 0ff04edcf5 any issues ? 2023-04-20 22:56:10 +02:00
fred bb671e35af Il s'agit également d'un portefeuille [Cesium](https://cesium.app). 2023-04-20 22:54:30 +02:00
fred d08e0c64ee On compte sur vous. 2023-04-20 22:53:20 +02:00
fred bc30327b7b On compte sur vous. 2023-04-20 22:52:40 +02:00
fred 9161005bc7 where is the manual? 2023-04-20 22:50:10 +02:00
fred 9850295ec9 Please README (Add issue if you have any trouble) 2023-04-20 22:43:06 +02:00
fred 6ceb3d73ce README 2023-04-20 22:30:23 +02:00
fred 2dba612eae MAKE G1BILLET & G1PASS 2023-04-20 22:15:18 +02:00
fred a7a214282d Add 3 images to make your Style ( _ : default / x : G1PASS / G1Ticket) 2023-04-19 22:12:16 +02:00
fred 8a038ecb4d security level - G1BILLET - pdf - G1PASS - png - PGP - 2023-04-19 04:55:43 +02:00
fred e18f6cfce1 DICE SECURITY LEVEL 2023-04-19 04:37:20 +02:00
fred 893b022755 /?montant=0&type=&dice=1 2023-04-19 04:24:23 +02:00
fred 7f62642fc7 choose security level (default dice=4) 2023-04-19 04:11:02 +02:00
fred 12752efa91 $(hostname -I | awk '{print $1}' | head -n 1) 2023-04-16 23:37:01 +02:00
fred 7be3a4d6c2 just z at 2023-04-16 22:07:15 +02:00
fred c77d30f985 adjust 2023-04-16 22:05:13 +02:00
fred d32b3ba0e9 precisely that way 2023-04-15 22:28:50 +02:00
fred d2f1991246 > ~/.zen/tmp/topgp
cat ~/.zen/tmp/topgp
2023-04-14 22:57:03 +02:00
fred e186ae7816 Random s & p 2023-04-08 15:37:46 +02:00
fred 53e7d07458 plus petit au centre 2023-04-04 20:33:20 +02:00
fred 45447d1689 Enjoy 2023-04-02 16:53:37 +02:00
fred cd5956a651 style=email@chezmoi.fr = xbian = PASS PGP + TW + G1 2023-03-31 20:07:41 +02:00
fred 441dc82943 http://g1billet.localhost:33101/?montant=___&style=xbian 2023-03-31 16:01:20 +02:00
fred 55d69c0ecd + PGP QR Code 2023-03-27 00:34:28 +02:00
fred 4f7af76b66 amzqr ---- PGP (PASS) mode 2023-03-26 18:04:38 +02:00
fred dae5400ba8 30 seconds waiting 2023-03-26 01:28:51 +01:00
fred 7defb00201 using PGP SALT/PEPPER QRCODE for pay process 2023-03-26 01:27:18 +01:00
fred 29df99b316 SALT=$EMAIL (style=$EMAIL) 2023-03-18 16:00:57 +01:00
fred 75dba89a1d DEFAULT 2 WORDS SECRETS 2023-03-16 22:31:53 +01:00
fred 2ae501e061 The perfect way to capture 'Monnaie Libre' on a paper. créez vos Bons au porteur G1BILLETS. La G1 sur un BILLET et IPFS pour les enregistrer. 2023-03-13 17:39:42 +01:00
fred a3a77870be log monitoring in tmp/G1BILLETS.log 2023-03-13 15:12:03 +01:00
fred 4e989a4d03 Easier install & systemd setup README include "test section" 2023-03-13 15:10:01 +01:00
fred 732c741ac5 jeu 2023-03-13 02:24:15 +01:00
fred 3a1ab3a45e sudo systemctl enable g1billet 2023-03-12 16:08:08 +01:00
fred 1fb8aedb1d Should help installation... plese try and report issue or make it better 2023-03-12 15:42:23 +01:00
fred fa16a218d9 Ce code est une production du [G1FabLab / G1SMS](https://g1sms.fr) 2023-03-10 03:04:49 +01:00
fred 0bc75181a3 "solian" Style Planche de 6 2023-03-10 02:52:16 +01:00
fred b7e9e7ba94 nouvelle mouture - extension TW 2023-03-10 02:45:12 +01:00
fred 8d7d069bcd Ticket with TW QRCode 2023-03-10 02:39:50 +01:00
fred 4709b552bc astro style + TW link 2023-03-10 01:39:11 +01:00
fred 5f0aee0456 $(date) log 2023-02-23 23:47:36 +01:00
fred 49fec0dd44 DEMO http://vmi891906.contaboserver.net:33101 2023-02-23 21:10:22 +01:00
fred 0211ea8820 New WAN demo : http://qwantic.com:33101/?montant=0&style=astro 2023-02-23 21:03:18 +01:00
fred 0e961d3a1a working API 2023-02-23 20:40:45 +01:00
fred 3586f0a56d SUB : http://qo-op.com:33101 & PUB : http://qo-op.com:33102 2023-02-23 20:08:40 +01:00
fred becbdb14db WELCOME ASTRONAUT $EMAIL 2023-02-23 20:05:05 +01:00
fred 05519d225e bug fix & API enhancement 2023-02-23 20:03:01 +01:00
fred 09e3ab20b5 Dropping 33102 to loop back into 33101 listening 2023-02-23 19:31:51 +01:00
fred 125ff2ec67 Activate salt API - ASTRO TW - http://g1billet.localhost:33101/?montant=0&style=moa1234@yopmail.com 2023-01-23 00:18:02 +01:00
fred f3b27bf3d7 redirect :33102 2023-01-22 23:54:44 +01:00
fred e9f5294a85 LOG REDIRECTION 2022-12-26 18:33:36 +01:00
fred b813488a3f isLAN 2022-12-18 21:28:30 +01:00
fred e9ab248755 push it 2022-12-07 15:39:00 +01:00
fred ef827827a4 NETWORK MICRO SERVICE -- PORTS : INPUT=33101 OUTPUT=33102 2022-12-07 15:37:50 +01:00
fred 10914605a0 G1BILLETS + 2022-12-07 15:35:49 +01:00
fred 57712ecb9b https://forum.monnaie-libre.fr/t/nouveau-g1-billets/14529/81 2022-12-07 14:33:34 +01:00
fred 2e45cc9a21 inline time 2022-12-07 00:33:47 +01:00
fred 247ba502b1 port 2022-12-07 00:18:36 +01:00
fred f2dc4cf28b RNAME="https://qo-op.com/33102" 2022-12-07 00:16:00 +01:00
fred 131917a891 hostname & https 2022-12-07 00:14:22 +01:00
fred 19acebbda3 port detect 2022-12-06 23:52:18 +01:00
fred 3ac3ef7f36 pidportinuse 2022-12-06 23:27:38 +01:00
fred 796c2bf1e1 CLEAN START DEAMON MODE 2022-12-06 23:23:30 +01:00
fred 8495fcfd2d DAEMON MODE OK 2022-12-06 23:16:47 +01:00
fred 5ec75b6c89 BEtter Network balance 2022-12-06 23:11:06 +01:00
fred e5c5afbbaa WELCOME TIMER 2022-12-06 22:51:12 +01:00
fred 275a6f8458 /// BROKEN PREFER DAEMON MODE 2022-12-06 22:39:40 +01:00
fred cf034c533f MAKE IT A NETWORK MICRO SERVICE -- PORTS : INPUT=33101 OUTPUT=33102 2022-12-06 22:37:05 +01:00
fred 37d5b86253 G1BILLET version "astro" - http service - http://g1billet.localhost:33101 2022-12-06 22:16:21 +01:00
fred 70eab68ea1 $attachment_location 2022-12-06 14:55:35 +01:00
fred 6ec561c296 dirname(__FILE__)."/tmp/g1billet/". 2022-12-06 14:51:16 +01:00
fred 35f933d208 tmp thing is happening better 2022-12-06 14:49:27 +01:00
fred aedf331ce6 keygen 2022-12-06 01:52:35 +01:00
fred d87ca3e66d astro version 2022-12-06 01:30:46 +01:00
fred 8e19ac39bc Style = astro (or email) 2022-12-06 01:00:20 +01:00
fred 11dc60cced astro TW patch 2022-11-24 22:45:03 +01:00
fred d2d7f568a1 Apparition du G1VOEUX 2022-08-18 16:14:43 +02:00
fred c3fa3363c0 lower res 2022-02-19 17:57:58 +01:00
fred 2a59d28bc3 lower res 2022-02-19 17:43:53 +01:00
fred e195b6161e lower res 2022-02-19 17:43:07 +01:00
fred e75a74b794 texte 2022-02-19 17:42:15 +01:00
fred 98f7de3381 lower res 2022-02-19 17:40:38 +01:00
fred 30daa95d44 changes 2022-02-19 17:38:40 +01:00
qo-op 480937c048 BON AU PORTEUR - MadeInZion/ASTROPORT 2021-06-06 21:25:46 +02:00
qo-op 448b52d22b Merge branch 'master' of https://git.p2p.legal/qo-op/G1BILLET 2021-06-02 03:09:35 +02:00
qo-op ce766c5f31 INVITATION JEu 2021-06-02 03:08:44 +02:00
qo-op 046b6961b0 Merge branch 'master' of https://git.p2p.legal/qo-op/G1BILLET 2021-05-21 00:45:59 +02:00
qo-op 362970077f TODO STORE XZUID & G1PUB into ASTROPORT/IPFS, as FUTURE travelers... 2021-05-21 00:44:19 +02:00
qo-op 7658be9e72 Merge branch 'master' of https://git.p2p.legal/qo-op/G1BILLET 2021-05-07 01:33:02 +02:00
qo-op 207d487e78 DU 2021-05-07 01:32:53 +02:00
qo-op 094dbb8265 Merge branch 'master' of https://git.p2p.legal/qo-op/G1BILLET 2021-05-07 01:31:50 +02:00
qo-op 9f6c15475f onenation.xyz 2021-05-07 01:31:40 +02:00
qo-op 74f233fac4 Merge branch 'master' of https://git.p2p.legal/qo-op/G1BILLET 2021-05-07 01:26:16 +02:00
qo-op 645cc357f4 onenation.xyz 2021-05-07 01:25:36 +02:00
qo-op bdbe9f862f EMBARQUEMENT 2021-04-27 16:09:07 +02:00
qo-op 2e82409568 CARTE EMBARQUEMENT ASTROPORT 2021-04-27 14:36:03 +02:00
qo-op b852051b81 ticket text adjust 2021-02-03 16:01:24 +01:00
qo-op 36abebff79 style xbian or ticket = one jpg 2021-02-03 15:56:02 +01:00
qo-op 23447afb09 xbian and ticket style are one jpg 2021-02-03 15:51:22 +01:00
qo-op 62c2e4d035 Fanch style=ticket 2021-02-03 15:14:08 +01:00
qo-op bd8d6c3f3e style=ticket (Fanch le colporteur) 2021-02-03 15:10:49 +01:00
qo-op a4a6d77c81 +-pointsize 20 -fill black -draw 'text 400,20 "'"${NOTERIB}"'"' \ 2021-01-31 01:30:28 +01:00
qo-op 401ec3337b Porte Monnaie Libre!! https://gchange.fr https://cesium.app 2021-01-31 01:26:14 +01:00
qo-op aa6c6f5edb ajout ${NOTERIB} 2021-01-31 01:11:43 +01:00
67 changed files with 2047 additions and 153 deletions

6
.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
.env
*.pyc
tmp/
_images/
DICE
♥Box

View File

@ -1,60 +1,398 @@
#!/bin/bash
################################################################################
# Author: Fred (support@qo-op.com)
# Version: 0.1
# Version: 1.0
# 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 and print 6 G1Billets de $MONTANT DU
# ${MY_PATH}/G1BILLETS.sh 5 986397643
# Create different king of G1BILLET(s) with $MONTANT DU or TW IPNS + ZENCARD
# ${MY_PATH}/G1BILLETS.sh 5 ticket 2 # MONTANT # STYLE # SECURITE
################################################################################
MONTANT="$1"
UNIQID="$2"
STYLE="$3"
## PLANCHE DE 6 BILLETS PAR DEFAUT
NBbillets=6
### COMMAND LINE MODE (DAEMON IS CALLING ITSELF) ###
if [[ $MONTANT != "daemon" ]]; then
[[ $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
pidportinuse=$(lsof -i :33102 | tail -n 1 | awk '{print $2}')
[[ $pidportinuse ]] && kill $pidportinuse && echo "KILLING NOT COLLECTED THREAD $pidportinuse"
# 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
[[ $MONTANT == "" || $MONTANT == "0" ]] && MONTANT="___"
# 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)
STYLE="$2"
# 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
DICE="$3"
# 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" /> -->
SECRET1="$4"
SECRET2="$5"
# CLEANING TEMP FILES
rm -Rf /tmp/g1billet/${UNIQID}
[[ $DICE != ?(-)+([0-9]) ]] && DICE=$(cat $MY_PATH/DICE 2>/dev/null) ## HOW MANY WORDS SECRETS
[[ $DICE != ?(-)+([0-9]) ]] && DICE=4
# ALLOWS ANY USER TO DELETE
chmod 777 /tmp/g1billet/${UNIQID}.pdf
echo "G1BILLET FACTORY MONTANT=$MONTANT DICE=$DICE"
echo "$STYLE : $MY_PATH/${IMAGES}/$STYLE"
exit
## 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 "&param=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

View File

@ -12,79 +12,276 @@ ME="${0##*/}"
############################################################################################################################################################
# ${MY_PATH}/G1BILLET_MAKE.sh "nu me ro test" "se cr et" 100 7sn9dKeCNEsHmqm1gMWNREke4YAWtNw8KG1YBSN8CmSh 97968583
############################################################################
export PATH="$HOME/.local/bin:$PATH"
NUMERO="$1"
SECRET="$2"
## 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}
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 [[ "$NUMERO" == "" || "$SECRET" == "" || "$MONTANT" == "" || "$NOTERIB" == "" || "$UNIQID" == "" ]]
if [[ "${SECRET1}" == "" || "$SECRET2" == "" || "$MONTANT" == "" || "$NOTERIB" == "" || "$UNIQID" == "" ]]
then
exit 1
echo "ERROR MISSING PARAM"
exit 1
fi
mkdir -p /tmp/g1billet/$UNIQID
BILLETNAME=$(echo $NUMERO | sed 's/ /_/g')
TAB=(${SECRET1} ${SECRET2})
FULLDICE=${#TAB[@]}
# 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"
mkdir -p ${MY_PATH}/tmp/g1billet/$UNIQID
BILLETNAME=$(echo ${SECRET1} | sed 's/ /_/g')
# Prepare BILLET qrcode verification URL
qrencode -s 5 -o "/tmp/g1billet/${UNIQID}/${BILLETNAME}.QR.png" "$NOTERIB"
IMAGESSTYLE="${IMAGES}/${STYLE}"
[[ ! -d ${MY_PATH}/${IMAGESSTYLE} ]] && IMAGESSTYLE="${IMAGES}/xastro" ## DEFAULT : TOOD CREATE UPlanet Style
# 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
# Prepare June logo color
case "$MONTANT" in
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"
;;
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"
;;
esac
# 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"
## 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
# 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
convert -font 'Liberation-Sans' \
-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"
## 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
rm -f /tmp/${BILLETNAME}.jpg

252
README.md
View File

@ -1,82 +1,238 @@
# G1BILLET
## Présentation
Ce code est un générateur de G1BILLETS
Ce code est un générateur de G1BILLETS qui utilise duniter.py keygen imagemagik amzqr
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
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.
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 G1 Billets à qui vous voulez.
Ensuite, offrez ces G1Billets à qui vous voulez.
Son détenteur peut alors utiliser l'identifiant/mot de passe pour accéder au portefeuille correspondant.
* [DISCUSSION/FAQ/DETAILS](https://forum.monnaie-libre.fr/t/nouveau-g1-billets/14529?u=qoop)
* [DEMO EN VIDEO](./G1BILLETS.mp4)
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).**
## Utilisation
Pour une utilisation en ligne de commande, adaptez ces quelques lignes
En ligne de commande, adaptez ces lignes à votre style ;)
```
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"
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"
```
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...
Personnalisez vos G1Billets, en modifiant les images dans ```images/$style``` (copiez-collez celles d'autres styles pour commencer le votre)
## Installation
* 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
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/)
## Pré-requis Installation
Pour Linux DEBIAN, Ubuntu, recommandé: [Linux Mint](https://www.linuxmint.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).
```
# Cloner le code de G1BILLET
mkdir -p $HOME/bin/
cd $HOME/bin/
# Création et clonage du code dans ""~/.zen"
mkdir -p ~/.zen
cd ~/.zen
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/
Ajoutez les dépendances nécessaire
```
sudo apt install python3 python3-pip imagemagick qrencode ttf-mscorefonts-installer
sudo pip3 install duniterpy
```
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:
```
<!-- <policy domain="coder" rights="none" pattern="PDF" /> -->
```
## Support
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.
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.
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)
Vous avez des questions? Contactez [Fred](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)
---
[G1SMS](https://g1sms.fr)
# 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
```
## 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
```
* 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 :
```
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
```
## LOG monitoring
```
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...**
---
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).
> :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 vos dons en JUNE
* [Fred](https://demo.cesium.app/#/app/wot/DsEx1pS33vzYZg4MroyBV9hCw98j1gtHEhwiZ5tK7ech/Fred)
Des questions? Contactez [support@qo-op.com](mailto:support@qo-op.com)
---
# [OpenCollective](https://opencollective.com/monnaie-libre)
## On compte sur vous.

12
add_desktop_shortcut.sh Executable file
View File

@ -0,0 +1,12 @@
#!/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 Normal file
View File

@ -0,0 +1,22 @@
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 Normal file
View File

@ -0,0 +1,162 @@
# 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)

7
g1billet.desktop Normal file
View File

@ -0,0 +1,7 @@
#!/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 Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
images/@astroport/fond.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 KiB

BIN
images/@astroport/g1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

BIN
images/@astroport/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

BIN
images/Brother_600x100.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 825 B

BIN
images/Brother_600x300.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
images/Brother_600x400.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
images/Brother_600x600.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

BIN
images/_/fond.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

BIN
images/_/g1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
images/_/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

BIN
images/astrologo_nb.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 147 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

BIN
images/g1magicien.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

BIN
images/jeu/fond.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

BIN
images/jeu/g1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

BIN
images/jeu/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

BIN
images/moa_net.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 280 KiB

BIN
images/money_coins.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
images/no_cloud.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
images/pirate_map.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

BIN
images/saubole/fond.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 161 KiB

BIN
images/saubole/g1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

BIN
images/saubole/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 KiB

BIN
images/web_internet.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

BIN
images/xastro/fond.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 KiB

BIN
images/xastro/g1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

BIN
images/xastro/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

View File

@ -2,22 +2,29 @@
$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']."'");
$attachment_location = "/tmp/g1billet/".$timestamp.".pdf";
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;
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/pdf");
header("Content-Type: application/".$file_type);
header("Content-Transfer-Encoding: Binary");
header("Content-Length:".filesize($attachment_location));
header("Content-Disposition: attachment; filename=".$timestamp.".pdf");
readfile($attachment_location);
unlink("/tmp/g1billet/".$timestamp.".pdf");
die();
header("Content-Disposition: attachment; filename=".$timestamp.".".$file_type);
readfile($attachment_location);
unlink(dirname(__FILE__)."/tmp/g1billet/".$timestamp.".".$file_type);
die();
} else {
die("Error: File not found.");
die("Error: File not found.".$attachment_location);
}
?>

35
install.sh Executable file
View File

@ -0,0 +1,35 @@
#!/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 Executable file
View File

@ -0,0 +1,896 @@
#!/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 Executable file
View File

@ -0,0 +1,16 @@
#!/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

40
setup_systemd.sh Executable file
View File

@ -0,0 +1,40 @@
#!/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

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

BIN
styles/fond/fond_blanc.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

BIN
styles/fond/fond_jeu.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

BIN
styles/fond/fond_monde1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 161 KiB

View File

Before

Width:  |  Height:  |  Size: 104 KiB

After

Width:  |  Height:  |  Size: 104 KiB

BIN
styles/fond/fond_xbian.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

BIN
styles/g1/g1_astro_nb.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
styles/g1/g1_astro_one.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

BIN
styles/g1/g1_astroport.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

BIN
styles/g1/g1_nb.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

BIN
styles/g1/g1_tim.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

BIN
styles/logo/logo_fanch.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 175 KiB

0
♥Box Normal file
View File