X-Git-Url: https://git.plutz.net/?p=confetti;a=blobdiff_plain;f=cgilite%2Fsession.sh;h=93cc2f4e93f88c46f3d4dfea29b79ef402b8cf09;hp=506e2f9f146c13919e65a9bbbd844391b96bbe9d;hb=34a5543f2f7be2b5892f8624481334a071e9d7ad;hpb=3c6444860aab3376e3b888f9d9b56e8efdaa03dc diff --git a/cgilite/session.sh b/cgilite/session.sh new file mode 100755 index 0000000..93cc2f4 --- /dev/null +++ b/cgilite/session.sh @@ -0,0 +1,88 @@ +#!/bin/sh + +[ -n "$include_session" ] && return 0 +include_session="$0" + +_DATE="$(date +%s)" +SESSION_TIMEOUT="${SESSION_TIMEOUT:-7200}" + +server_key(){ + IDFILE="${IDFILE:-${_DATA:-.}/serverkey}" + if [ "$(stat -c %s "$IDFILE")" -ne 512 ] || ! cat "$IDFILE"; then + dd count=1 bs=512 if=/dev/urandom \ + | tee "$IDFILE" + fi 2>&- +} + +slopecode(){ + # 6-Bit Code that retains sort order of input data, while beeing safe to use + # in ascii transmissions, unix file names, HTTP URLs, and HTML attributes + + uuencode -m - | sed ' + 1d;$d; + y;ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/;0123456789:=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz; + ' +} + +session_mac(){ + local info + [ $# -eq 0 ] && info="$(cat)" || info="$*" + + if which openssl >/dev/null; then + printf %s "$info" |openssl dgst -sha1 -hmac "$(server_key)" -binary |slopecode + else + { printf %s "$info"; server_key; } |sha256sum |cut -d\ -f1 + fi +} + +randomid(){ + dd bs=12 count=1 if=/dev/urandom 2>&- \ + | slopecode +} + +timeid(){ + d=$(($_DATE % 4294967296)) + { printf "$( + printf \\%o \ + $((d / 16777216 % 256)) \ + $((d / 65536 % 256)) \ + $((d / 256 % 256)) \ + $((d % 256)) + )" + dd bs=8 count=1 if=/dev/urandom 2>&- + } | slopecode +} + +checkid(){ grep -m 1 -xE '[0-9a-zA-Z:=]{16}'; } + +transid(){ + # transaction ID to modify a given file + local file="$1" + session_mac "$(stat -c %F%i%n%N%s%Y "$file" 2>&-)" "$SESSION_ID" +} + +update_session(){ + local session sid time sig checksig + + read -r sid time sig <<-END + $(POST session_key || COOKIE session) + END + + checksig="$(session_mac "$sid" "$time")" + + if ! [ "$checksig" = "$sig" \ + -a "$time" -ge "$_DATE" \ + -a "$(printf %s "$sid" |checkid)" ] 2>&- + then + debug "Setting up new session" + sid="$(randomid)" + fi + + time=$(( $_DATE + $SESSION_TIMEOUT )) + sig="$(session_mac "$sid" "$time")" + printf %s\\n "${sid} ${time} ${sig}" +} + +SESSION_KEY="$(update_session)" +SET_COOKIE 0 session="$SESSION_KEY" Path=/ SameSite=Strict HttpOnly +SESSION_ID="${SESSION_KEY%% *}"