]> git.plutz.net Git - webpoll/commitdiff
Merge commit 'a225474fb413aa9b5d834abbf1c9b65c397d7242'
authorPaul Hänsch <paul@plutz.net>
Thu, 26 Aug 2021 00:43:16 +0000 (02:43 +0200)
committerPaul Hänsch <paul@plutz.net>
Thu, 26 Aug 2021 00:43:16 +0000 (02:43 +0200)
1  2 
cgilite/cgilite.sh
cgilite/session.sh
cgilite/storage.sh

diff --combined cgilite/cgilite.sh
index 9fa56eef0633f22e7fa5d8f901ddf776143a6a55,7f828ddd6c8e2234c7cb3e2625505b5796e8eb77..7f828ddd6c8e2234c7cb3e2625505b5796e8eb77
@@@ -1,6 -1,6 +1,6 @@@
  #!/bin/sh
  
- # Copyright 2017 - 2020 Paul Hänsch
+ # Copyright 2017 - 2021 Paul Hänsch
  #
  # This is CGIlite.
  # A collection of posix shell functions for writing CGI scripts.
@@@ -32,6 -32,9 +32,9 @@@ cgilite_timeout=
  
  PATH(){ 
    local str seg out
+   # normalize path
+   # read from stdin if no arguments are provided
    [ $# -eq 0 ] && str="$(cat)" || str="$*"
    while [ "$str" ]; do
      seg=${str%%/*}; str="${str#*/}"
    [ "${str}" -a "${out}" ] && printf %s "$out" || printf %s/ "${out%/}"
  }
  
- HEX_DECODE='
-   s;\\;\\\\;g; :HEXDECODE_X; s;%([^0-9A-F]);\\045\1;g; tHEXDECODE_X;
-   # Hexadecimal { %00 - %FF } will be transformed to octal { \000 - \377 } for posix printf
-   s;%[0123].;&\\0;g; s;%[4567].;&\\1;g; s;%[89AB].;&\\2;g; s;%[CDEF].;&\\3;g;
-   s;%[048C][0-7]\\.;&0;g; s;%[048C][89A-F]\\.;&1;g; s;%[159D][0-7]\\.;&2;g; s;%[159D][89A-F]\\.;&3;g;
-   s;%[26AE][0-7]\\.;&4;g; s;%[26AE][89A-F]\\.;&5;g; s;%[37BF][0-7]\\.;&6;g; s;%[37BF][89A-F]\\.;&7;g;
-   s;%.[08](\\..);\10;g; s;%.[19](\\..);\11;g; s;%.[2A](\\..);\12;g; s;%.[3B](\\..);\13;g;
-   s;%.[4C](\\..);\14;g; s;%.[5D](\\..);\15;g; s;%.[6E](\\..);\16;g; s;%.[7F](\\..);\17;g;
- '
  HEX_DECODE(){
-   printf -- "$(printf %s "$1" |sed -E "$HEX_DECODE")"
+   local pfx="$1" in="$2" out
+   # Print out Data encoded as Hex
+   #
+   # Arguments:
+   # pfx - required, prefix for a hex tupel, e.g. "\x", "%" "\", may be empty
+   # in - required, string to be decoded
+   #
+   # anything that does not constitute a tupel of valid Hex numerals
+   # will be copied to the output literally
+   while [ "$in" ]; do
+     case $in in
+       "$pfx"[0-9a-fA-F][0-9a-fA-F]*) in="${in#${pfx}}";;
+       \\*) in="${in#?}"; out="${out}\\\\"; continue;;
+        %*) in="${in#?}"; out="${out}%%";  continue;;
+         *) out="${out}${in%"${in#?}"}"; in="${in#?}"; continue;;
+     esac;
+     # Hex escaes for printf (e.g. \x41) are not portable 
+     # The portable way for Hex output is transforming Hex to Octal
+     # (e.g. \x41 = \101)
+     case $in in
+         [0123]?*) out="${out}\\0";;
+         [4567]?*) out="${out}\\1";;
+       [89aAbB]?*) out="${out}\\2";;
+       [c-fC-F]?*) out="${out}\\3";;
+     esac
+     case $in in
+             [048cC][0-7]*) out="${out}0";;
+        [048cC][89a-fA-F]*) out="${out}1";;
+             [159dD][0-7]*) out="${out}2";;
+        [159dD][89a-fA-F]*) out="${out}3";;
+            [26aAeE][0-7]*) out="${out}4";;
+       [26aAeE][89a-fA-F]*) out="${out}5";;
+            [37bBfF][0-7]*) out="${out}6";;
+       [37bBfF][89a-fA-F]*) out="${out}7";;
+     esac
+     case $in in
+        ?[08]*) out="${out}0";;
+        ?[19]*) out="${out}1";;
+       ?[2aA]*) out="${out}2";;
+       ?[3bB]*) out="${out}3";;
+       ?[4cC]*) out="${out}4";;
+       ?[5dD]*) out="${out}5";;
+       ?[6eE]*) out="${out}6";;
+       ?[7fF]*) out="${out}7";;
+     esac
+     in="${in#?}"
+     in="${in#?}"
+   done
+   printf -- "$out"
  }
  
  if [ -z "$REQUEST_METHOD" ]; then
      kill $cgilite_watchdog
  
      SERVER_PROTOCOL="${SERVER_PROTOCOL%${CR}}"
-     PATH_INFO="$(HEX_DECODE "${REQUEST_URI%\?*}" |PATH)"
+     PATH_INFO="$(HEX_DECODE "${REQUEST_URI%\?*}" |PATH)"
      [ "${REQUEST_URI}" = "${REQUEST_URI#*\?}" ] \
      && QUERY_STRING='' \
      || QUERY_STRING="${REQUEST_URI#*\?}"
@@@ -145,7 -188,7 +188,7 @@@ cgilite_value()
      str="${str#*&${name}=}"
      cnt=$((cnt - 1))
    done
-   printf -- "$(printf %s "${str%%&*}" |sed -E 's;\+; ;g;'"$HEX_DECODE")"
+   HEX_DECODE % "$(printf %s "${str%%&*}" |tr + \  )"
  }
  
  cgilite_keys(){
@@@ -185,7 -228,7 +228,7 @@@ HEADER()
  }
  
  COOKIE(){
-   HEX_DECODE "$(
+   HEX_DECODE "$(
      HEADER Cookie \
      | grep -oE '(^|; ?)'"$1"'=[^;]*' \
      | sed -En "${2:-1}"'{s;^[^=]+=;;; s;\+; ;g; p;}'
diff --combined cgilite/session.sh
index 8929ab3de62638fa4084cbf3f6d50ba5510ec960,ca931fad9aa662ec338820bdc88be9f5018aba24..ca931fad9aa662ec338820bdc88be9f5018aba24
@@@ -16,8 -16,16 +16,16 @@@ f
  if which openssl >/dev/null; then
    session_mac(){ { [ $# -gt 0 ] && printf %s "$*" || cat; } | openssl dgst -sha1 -hmac "$(server_key)" -binary |slopecode; }
  else
-   # sham hmac if openssl is unavailable
-   session_mac(){ { [ $# -gt 0 ] && printf %s "$*" || cat; server_key; } | sha256sum |cut -d\  -f1; }
+   # Gonzo MAC if openssl is unavailable
+   session_mac(){
+     { server_key | dd status=none bs=256 count=1 skip=1
+       { server_key | dd status=none bs=256 count=1
+         [ $# -gt 0 ] && printf %s "$*" || cat
+       } \
+       | sha256sum -;
+     } \
+     | sha256sum | cut -d\  -f1
+   }
  fi
  
  server_key(){
diff --combined cgilite/storage.sh
index 61eec88fb2cee63f706a634eaa48c85a09ef1967,77ee29c06243eae9359c03125626a46f498cded4..77ee29c06243eae9359c03125626a46f498cded4
@@@ -1,6 -1,6 +1,6 @@@
  #!/bin/sh
  
- # Copyright 2018, 2019 Paul Hänsch
+ # Copyright 2018, 2019, 2021 Paul Hänsch
  #
  # This is a file format helper, part of CGIlite.
  # 
@@@ -25,41 -25,40 +25,40 @@@ BR=
  '
  
  LOCK(){
-   local lock timeout block
-   lock="${1}.lock"
-   timeout="${2-20}"
-   if [ \! -w "${lock%/*}" ] || [ -e "$lock" -a \! -d "$lock" ]; then
+   local lock="${1}.lock" timeout="${2-20}" block
+   if [ \! -w "${lock%/*}" ] || [ -e "$lock" -a \! -f "$lock" ]; then
      debug "Impossible to get lock: $lock"
      return 1
    fi
  
-   while ! mkdir "$lock" 2>&-; do
-     block="$(cat "$lock/pid" || printf 1)"
-     if ! { ps -eo pid |grep -qwF "$block"; }; then
-       debug "Overriding stale lock: $lock"
-       break
-     fi
-     if [ $timeout -le 0 ]; then
-       debug "Timeout while trying to get lock: $lock"
-       return 1
+   while [ $timeout -gt 0 ]; do
+     printf '%i\n' $$ >>"${lock}"
+     read block <"$lock"
+     if [ "$block" = $$ ]; then
+       return 0
+     elif ! { ps -eo pid |grep -qwF "$block"; }; then
+       debug "Trying to override stale lock: $lock"
+       if LOCK "$lock" 1; then
+         rm -- "$lock"
+         RELEASE "$lock"
+       fi
+     else
+       timeout=$((timeout - 1))
+       [ $timeout -gt 0 ] && sleep 1
      fi
-     timeout=$((timeout - 1))
-     sleep 1
    done
-   printf '%i\n' $$ >"${lock}/pid"
-   return 0
+   debug "Timeout while trying to get lock: $lock"
+   return 1
  }
  
  RELEASE(){
-   local lock
-   lock="${1}.lock"
-   if [ "$(cat "$lock/pid")" = "$$" ]; then
-     rm "$lock/pid"
-     if ! rmdir "$lock"; then
-       debug "Cannot remove tainted lock: $lock"
-       printf '%i\n' $$ >"${lock}/pid"
-       return 1
-     fi
+   local lock="${1}.lock" block
+   read block <"$lock"
+   if [ "$block" = $$ ]; then
+     rm -- "$lock"
      return 0
    else
      debug "Refusing to release foreign lock: $lock"