]> git.plutz.net Git - webpoll/commitdiff
Squashed 'cgilite/' changes from 8be65ce..dcab989
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)
dcab989 much faster hex decode function
07b4b96 simpler lock algorithm using files
38702db improved gonzo mac if openssl is unavailable

git-subtree-dir: cgilite
git-subtree-split: dcab9893c3e08b2ad0d0e9246b8ceefc3d40b9f8

cgilite.sh
session.sh
storage.sh

index 9fa56eef0633f22e7fa5d8f901ddf776143a6a55..7f828ddd6c8e2234c7cb3e2625505b5796e8eb77 100755 (executable)
@@ -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 @@ cgilite_timeout=2
 
 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#*/}"
@@ -45,18 +48,58 @@ PATH(){
   [ "${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
@@ -79,7 +122,7 @@ 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 @@ 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 @@ HEADER(){
 }
 
 COOKIE(){
-  HEX_DECODE "$(
+  HEX_DECODE "$(
     HEADER Cookie \
     | grep -oE '(^|; ?)'"$1"'=[^;]*' \
     | sed -En "${2:-1}"'{s;^[^=]+=;;; s;\+; ;g; p;}'
index 8929ab3de62638fa4084cbf3f6d50ba5510ec960..ca931fad9aa662ec338820bdc88be9f5018aba24 100755 (executable)
@@ -16,8 +16,16 @@ fi
 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(){
index 61eec88fb2cee63f706a634eaa48c85a09ef1967..77ee29c06243eae9359c03125626a46f498cded4 100755 (executable)
@@ -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 @@ 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"