From 2219ce7538aa7624d4495438f3783d983fd47b8f Mon Sep 17 00:00:00 2001 From: Zergling_man Date: Wed, 27 Sep 2023 16:39:49 +1000 Subject: [PATCH] I often want these elsewhere --- creds_getter.sh | 69 ++++++++++++++++++ mkcerts.sh | 169 +++++++++++++++++++++++++++++++++++++++++++++ pixivdownloader.py | 8 +++ port_forward.sh | 38 ++++++++++ search.sh | 37 ++++++++++ 5 files changed, 321 insertions(+) create mode 100644 creds_getter.sh create mode 100644 mkcerts.sh create mode 100644 pixivdownloader.py create mode 100755 port_forward.sh create mode 100755 search.sh diff --git a/creds_getter.sh b/creds_getter.sh new file mode 100644 index 0000000..3ce4b57 --- /dev/null +++ b/creds_getter.sh @@ -0,0 +1,69 @@ +function _scan_config +{ + c="$HOME/.config/"; i=0 # for funny wc -l + while read dirname; do + if [ -d "$c$dirname" -a -a "$c$dirname/accounts" ]; then + dirs[$i]="$dirname" + i=$(($i+1)) + fi + done <<< $(ls "$c") +} + +function _select_conf +{ + for n in "${dirs[@]}"; do + if [ "$1" == "$n" ]; then conf="$HOME/.config/$1/accounts"; fi + done + if [ -z "$conf" ]; then # Still haven't picked one means the input wasn't a valid target + echo "no such conf in $1 (specifically $HOME/.config/$1/accounts)" + return 1 + fi +} + +function creds +{ + local conf OPTIND # Specifically putting these on same line so I can have funny number of lines. + while getopts 'hpf:' o; do case "${o}" in + h) echo 'Usage: creds [-p] [-f conf file] [~/.config file] [account]'; return;; + p) print=set; break;; + f) conf=$OPTARG; break;; + esac done + shift $((OPTIND-1)) + + # Selecting config file + if [ -z "$conf" ]; then + declare -a dirs + _scan_config + # Displaying config files available + if [ -z "$1" ]; then + for n in "${dirs[@]}"; do echo $n; done + return + fi + _select_conf $1 || return + shift + fi + + # Selecting account + # Displaying accounts is mashed up among it + local flag + while read lin; do + if [ -z $flag ]; then + if [ -z $1 ]; then + echo $lin + else + read headers <<< "$lin" + fi + else + read -a lin <<< "$lin" + if [ -z $1 ]; then + echo "${lin[0]}" + elif [ "$1" == "${lin[0]}" ]; then + if [ -z $print ] + then read $headers <<< ${lin[*]} + else echo ${lin[*]} + fi + fi + fi + flag=set + done < "$conf" +} \ No newline at end of file diff --git a/mkcerts.sh b/mkcerts.sh new file mode 100644 index 0000000..0a5c942 --- /dev/null +++ b/mkcerts.sh @@ -0,0 +1,169 @@ +#Do less often +function generateCA { openssl req -x509 -newkey rsa:4096 -keyout $1.key -out $1.crt -sha256 -days 1825 -noenc -config $2; } # $1=kaka $2=caconf + +#Do more often +function generatePriv { openssl req -new -newkey rsa:4096 -keyout $1.key -out $1.csr -sha256 -noenc -config $2; } # $1=live $2=nuconf +# Should break this into two functions actually. + +#... Do most often? Maybe don't need to remake privkey. +function signCert { openssl x509 -req -in $1.csr -out $1.crt -CA $2.crt -CAkey $2.key -days 400 -copy_extensions copyall; rm $1.csr ; } # $1=live $2=kaka +# REMINDER TO PUT DIFFERENT NAMES ON THE CERTS FROM NOW ON TO MAKE THINGS CLEARER +# No. Fuck you faggot, kaka and live are obvious enough. + +# GENERIC UTILS + +function ifsrev { __temp=$(tr "$2" '\n' <<< "$1" | tac | tr '\n' "$2"); echo -n ${__temp:0:-1}; } +function b64u { cat | base64 -w 0 | tr '/+' '_-' | tr -d '= '; } # u for url-safe +function short256 { __temp=$(cat | sha256sum); echo -n ${__temp:0:-3}; } +function hex2bin { cat | sed 's/\([0-9a-f]\{2\}\)/\\\\\\x\1/g' | xargs printf; } + +# UTILS + +function getCAURLs +{ + declare -A CAs + CAs[LE]=https://acme-v02.api.letsencrypt.org/directory + CAs[LEtest]=https://acme-staging-v02.api.letsencrypt.org/directory + CAs[buypass]=https://api.buypass.com/acme/directory + CAs[buypasstest]=https://api.test4.buypass.no/acme/directory + CAs[ZSSL]=https://acme.zerossl.com/v2/DV90 + CAs[sslcom_rsa]=https://acme.ssl.com/sslcom-dv-rsa + CAs[sslcom_ecc]=https://acme.ssl.com/sslcom-dv-ecc + CAs[jewgle]=https://dv.acme-v02.api.pki.goog/directory + CAs[jewgletest]=https://dv.acme-v02.test-api.pki.goog/directory + endpoints=$(curl -s ${CAs[$1]}) + export endpoints # I don't know if this works +} # $1=LE + +function readACME +{ + # Extract signature info from key: + read hex exp <<< $(openssl rsa -in account.key -noout -text | tr -d ': \r\n' | sed -E 's/^.*modulus00([a-f0-9]+)publicExponent[0-9]+\(0x([0-9a-f]+)\).*$/\1 \2/') + # And prepare it for sending to ACME server: + hex=$(hex2bin <<< "$hex" | b64u) + exp=$([ $((${#exp}%2)) = 0 ] || echo -n 0; echo $exp) # There's probably an easier way than this, but it works and makes sense so whatever. + exp=$(hex2bin <<< "$exp" | b64u) # Apparently this one goes in URLs. OR NOT, THE OTHER ONE DOES. + jerk='{"e": "'$exp'", "kty": "RSA", "n": "'$hex'"}' + sig='{"alg":"RS256", "jwk": '$jerk'}' # Keys must be sorted. + thumb=$(echo -n "$jerk" | tr -d ' ' | short256 | hex2bin | b64u) # How many times can you b64 a bowl of ramen before it begins questioning its existence +} + +function loadkid +{ + kid=$1 + if [ -z "$kid" -a -e "kid" ]; then kid=$(cat kid); fi + if [ -n "$kid" ]; then + sig='{"alg": "RS256", "kid": "'$kid'"}' + fi +} + +function getNonce +{ + # Get a nonce (nigger): + nonce_resp=$1 + if [ -z "$nonce_resp" ]; then + nonce_resp=$(curl -si $(echo $endpoints | jq -r .newNonce)) + fi + grep -i 'replay-nonce' <<< "$nonce_resp" | tr -d "\r" | grep -Eo '[0-9a-zA-Z_\-]+$' # Fucking Windows line endings +} + +# CHALLENGES + +function order +{ + readACME # get thumb. It fucks up sig but I don't care, sendreq fixes it. + declare -a urls + i=0 + doms=$(jq -r '.[]' <<< "$1") + while read dom; do + urls[$i]=$(challenge "$(sendreq $dom)") # this is meant to be signed but it seems to work without it...? But sign it just in case it's a test-only thing. + i=$((i+1)) + done <<< "$doms" + systemctl reload named # Actually update DNS for real final7 + sleep 120 # Wait for DNS to update. Generally it won't have been requested in ages so it won't be in any caches. + for url in ${urls[@]}; do + sendreq $url '{}' | jq '(.validationRecord | map(.hostname) | join(" "))+" "+.status' # need empty dict to tell server to validate challenge, empty body only checks status. Just another certified ACME moment. + done + sleep 30 # Wait for challenges to complete - the previous call can return before the challenge completes. + for url in ${urls[@]}; do + sendreq $url | jq '(.validationRecord | map(.hostname) | join(" "))+" "+.status' + done +} + +function challenge +{ + read dom url tok <<< $(jq -r '.identifier.value+" "+(.challenges | .[] | select(.type == "dns-01") | .url+" "+.token)' <<< "$1") + tik=$(echo -n "$tok.$thumb" | short256 | hex2bin | b64u) + dnsname="/var/named/$(ifsrev $dom .).zone" + inc=$(grep -Eo 'SOA [^ ]+ [^ ]+ [0-9]+' $dnsname | grep -Eo '[0-9]+$') + if ! grep -i _ACME-CHALLENGE $dnsname > /dev/null; then echo >> $dnsname; echo "_ACME-CHALLENGE 300 TXT aa" >> $dnsname; fi + sed -i -e 's/^_ACME-CHALLENGE 300 TXT .*$/_ACME-CHALLENGE 300 TXT '$tik'/' -e 's/SOA\t\([^\t]*\)\t\([^\t]*\)\t[0-9]*/SOA \1 \2 '$((inc+1))'/' $dnsname # Actually update the DNS + echo $url # Then give back the verification URL to be used later +} + +# CORE ACTIONS + +function genACMEkey { openssl genrsa -traditional 2048 > account.key; } + +function registerAcc +{ + # Create account: + readACME + url=$(echo $endpoints | jq -r .newAccount) + req='{"termsOfServiceAgreed": true, "contact": ["mailto:zerglingman@fedora.email"]}' + out=$(sendreq "$url" "$req" yes) + loc=$(grep -i 'location' <<< "$out" | grep -io http.*$) + loadkid $loc + echo $loc +} + +function getcert +{ + conf=$1 + shift + url=$(echo $endpoints | jq -r .newOrder) + req='{"identifiers": [' + for n in $@; do + req=$req'{"type": "dns", "value": "'$n'"}, ' + done + req=${req:0:-2}']}' + order=$(sendreq $url "$req") + # I can just access the headers lol + orderurl=$(grep -i location <<< "$req_heads" | grep -io http.*$) + auths=$(jq '.authorizations' <<< "$order") + finalise=$(jq -r '.finalize' <<< "$order") + order "$auths" + openssl req -new -key live.key -out live.csr -sha256 -noenc -config $conf -outform DER + # I guess I should just include the conf file + sendreq $finalise '{"csr":"'$(cat live.csr | b64u)'"}' + certurl=$(sendreq $orderurl | jq -r .certificate) + curl $certurl > out.crt +} + +# SERVER COMMUNICATION + +function sendreq +{ + loadkid # Just to make sure the sig is set correctly. It won't overwrite it unless it should be. + url=$1; if [ -n "$2" ]; then req=$(b64u <<< "$2"); else req=""; fi + if [ -z "$nonce" ]; then nonce=$(getNonce); fi + data=$(jq '.+{"nonce":"'$nonce'","url":"'$url'"}' <<< "$sig" | tr -d '\r\n' | tr -s ' ' ' ' | sed -e 's/{ /{/g' -e 's/ }/}/g') # Keys don't need to be sorted here, but they still are. + # I don't know why the URL has to be in the body that is sent to the URL. + # ACME is a terrible protocol. + body=$(b64u <<< "$data") + sig2=$(echo -n "$body.$req" | openssl dgst -sha256 -sign account.key | b64u) + mexican='{"protected": "'$body'", "payload": "'$req'", "signature": "'$sig2'"}' # Because it's a jose + req_resp=$(curl -isH "Content-type:application/jose+json" $url --data "$mexican" | tr -d "\r") # Here is the line that does the work + req_heads=$(sed -n 1,/^$/p <<< "$req_resp") + req_resp=$(sed 1,/^$/d <<< "$req_resp") + nonce=$(getNonce "$req_heads") + if [ -n "$3" ]; then echo "$req_heads"; fi + echo $req_resp +} + +# MAIN + +getCAURLs $1 +shift +loadkid +$* \ No newline at end of file diff --git a/pixivdownloader.py b/pixivdownloader.py new file mode 100644 index 0000000..f22ae2d --- /dev/null +++ b/pixivdownloader.py @@ -0,0 +1,8 @@ +import requests as r +import regex + +headers={'cookie':'privacy_policy_notification=0; p_ab_id=0; p_ab_id_2=6; p_ab_d_id=98792899; FANBOXSESSID=38848234_x16jnBtsVgjUX6NpW14obc5Odfq1tn6u; privacy_policy_agreement=3'} # This needs to be refreshed every time. +needle=regex.compile('(https://downloads\.fanbox\.cc/images/post/\d+/[a-zA-Z0-9]+\.[a-z]{3,4})') + +blob=open('post.txt').read() +for a in needle.findall(blob): open(a[a.rfind('/')+1:],'wb').write(r.get(a,headers=headers).content) \ No newline at end of file diff --git a/port_forward.sh b/port_forward.sh new file mode 100755 index 0000000..cc0fb1b --- /dev/null +++ b/port_forward.sh @@ -0,0 +1,38 @@ +if [ $(id -u) -gt 0 ]; then + echo "This script must be run as root." + exit +fi + +port=$1 +echo "port" $port +ip=$(ip ad sh eth0 | grep -Eo "inet [0-9]+\.[0-9]+\.[0-9]+\.[0-9]+" | grep -Eo "[^a-z ]+") + +#Get list of already forwarded ports and what IPs +remotes=$(sudo -u wisknort ssh root@jasmine iptables -nt nat -L PREROUTING | grep -Eo 'dpt:[0-9]+ to:[0-9\.]+') +locals=$(iptables -nt mangle -L OUTPUT | grep -Eo 'spt:[0-9]+') + +#run once per startup +if [ ! -e /tmp/ipeed ]; then + ip rule add fwmark 0x1 lookup vidya + ip route add default via 192.168.18.202 table vidya + sudo -u wisknort ssh root@jasmine sysctl -w net.ipv4.ip_forward=1 + touch /tmp/ipeed +fi + +#run once per port to forward +#local +if [ -z "$(grep "spt:$port" <<< "$locals")" ]; then + echo "sport" $port + iptables -t mangle -A OUTPUT -p tcp --sport $port -j MARK --set-mark 0x1 + iptables -t mangle -A OUTPUT -p udp --sport $port -j MARK --set-mark 0x1 +else + echo "local already forwarded" +fi +#jasmine +if [ -z "$(grep "dpt:$port to:$ip" <<< "$remotes")" ]; then + echo "dpt" $port + sudo -u wisknort ssh root@jasmine "iptables -t nat -A PREROUTING -p tcp --dport $port -j DNAT --to $ip" + sudo -u wisknort ssh root@jasmine "iptables -t nat -A PREROUTING -p udp --dport $port -j DNAT --to $ip" +else + echo "remote already forwarded" +fi diff --git a/search.sh b/search.sh new file mode 100755 index 0000000..7b0eab7 --- /dev/null +++ b/search.sh @@ -0,0 +1,37 @@ +declare -A sources +sources[ddg]="https://duckduckgo.com/?q=" +sources[gelb]="https://gelbooru.com/index.php?page=post&s=list&tags=" +sources[wiki]="https://en.wikipedia.org/w/index.php?title=Special:Search&fulltext=Search&ns0=1&go=Go&search=" +sources[gfl]="https://iopwiki.com/index.php?title=Special:Search&go=Go&search=" +sources[nyaa]="https://nyaa.si/?f=0&c=1_2&q=" +sources[itch]="https://itch.io/search?q=" +sources[bandcamp]="https://bandcamp.com/search?q=" +sources[pip]="https://pypi.org/search/?q=" +sources[fdroid]="https://search.f-droid.org/?lang=en&q=" +sources[wiby]="http://wiby.me/?q=" +sources[arch]="https://wiki.archlinux.org/index.php?go=Go&search=" +sources[mal]="https://myanimelist.net/anime.php?cat=anime&type=0&score=0&status=0&p=0&r=0&sm=0&sd=0&sy=0&em=0&ed=0&ey=0&c%5B%5D=a&c%5B%5D=b&c%5B%5D=c&c%5B%5D=f&q=" +#https://apibay.org/q.php?cat=&q= +#https://apibay.org/t.php?id= +mag() { echo "magnet:?xt=urn:btih:$1&dn=${*:2}&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969%2Fannounce&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A6969%2Fannounce&tr=udp%3A%2F%2Ftracker.bittor.pw%3A1337%2Fannounce&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&tr=udp%3A%2F%2Fbt.xxx-tracker.com%3A2710%2Fannounce&tr=udp%3A%2F%2Fpublic.popcorn-tracker.org%3A6969%2Fannounce&tr=udp%3A%2F%2Feddie4.nl%3A6969%2Fannounce&tr=udp%3A%2F%2Ftracker.torrent.eu.org%3A451%2Fannounce&tr=udp%3A%2F%2Fp4p.arenabg.com%3A1337%2Fannounce&tr=udp%3A%2F%2Ftracker.tiny-vps.com%3A6969%2Fannounce&tr=udp%3A%2F%2Fopen.stealth.si%3A80%2Fannounce"; } +function smolhelp() +{ + echo "Known search engines: ${!sources[@]}" +} + +function bighelp() +{ + echo "Configured search engines:" + for key in ${!sources[@]}; do + echo "$key: ${sources[$key]}" + done +} + +while getopts "hH" o;do case "${o}" in + h) smolhelp; exit;; + H) bighelp; exit;; +esac done + +SOURCE=$1 +shift 1 +exo-open "${sources[$SOURCE]}$*"