Squashed 'cgilite/' content from commit a1caf91
[confetti] / session.sh
1 #!/bin/sh
2
3 [ -n "$include_session" ] && return 0
4 include_session="$0"
5
6 _DATE="$(date +%s)"
7 SESSION_TIMEOUT="${SESSION_TIMEOUT:-7200}"
8
9 server_key(){
10   IDFILE="${IDFILE:-${_DATA:-.}/serverkey}"
11   if [ "$(stat -c %s "$IDFILE")" -ne 512 ] || ! cat "$IDFILE"; then
12     dd count=1 bs=512 if=/dev/urandom \
13     | tee "$IDFILE"
14   fi 2>&-
15 }
16
17 slopecode(){
18   # 6-Bit Code that retains sort order of input data, while beeing safe to use
19   # in ascii transmissions, unix file names, HTTP URLs, and HTML attributes
20
21   uuencode -m - | sed '
22     1d;$d; 
23     y;ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/;0123456789:=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz;
24   '
25 }
26
27 randomid(){
28   dd bs=12 count=1 if=/dev/urandom 2>&- \
29   | slopecode
30 }
31
32 timeid(){
33   d=$(($_DATE % 4294967296))
34   { printf "$(
35       printf \\%o \
36         $((d / 16777216 % 256)) \
37         $((d / 65536 % 256)) \
38         $((d / 256 % 256)) \
39         $((d % 256))
40     )"
41     dd bs=8 count=1 if=/dev/urandom 2>&-
42   } | slopecode
43 }
44
45 checkid(){ grep -m 1 -xE '[0-9a-zA-Z:=]{16}'; }
46
47 transid(){
48   # transaction ID to modify a given file
49   local file="$1"
50   { stat -c %F%i%n%N%s%Y "$file" 2>&-
51     printf %s "$SESSION_ID"
52     server_key
53   } | sha256sum | cut -d\  -f1
54 }
55
56 update_session(){
57   local session sid time sig serverkey checksig
58
59   IFS=- read -r sid time sig <<-END
60         $(POST session_key || COOKIE session)
61         END
62   serverkey="$(server_key)"
63   
64   checksig="$(printf %s "$sid" "$time" "$serverkey" | sha256sum)"
65   checksig="${checksig%% *}"
66   
67   if ! [ "$checksig" = "$sig" \
68     -a "$time" -ge "$_DATE" \
69     -a "$(printf %s "$sid" |checkid)" ] 2>&-
70   then
71     debug "Setting up new session"
72     sid="$(randomid)"
73   fi
74
75   time=$(( $_DATE + $SESSION_TIMEOUT ))
76   sig="$(printf %s "$sid" "$time" "$serverkey" |sha256sum)"
77   sig="${sig%% *}"
78   printf %s\\n "${sid}-${time}-${sig}"
79 }
80
81 SESSION_KEY="$(update_session)"
82 SET_COOKIE 0 session="$SESSION_KEY" Path=/ SameSite=Strict HttpOnly
83 SESSION_ID="${SESSION_KEY%%-*}"