]> git.plutz.net Git - serve0/commitdiff
Merge commit 'e6fbe5cc2866010baffad842e49027f75f300633'
authorPaul Hänsch <paul@plutz.net>
Sat, 13 Feb 2021 21:29:59 +0000 (22:29 +0100)
committerPaul Hänsch <paul@plutz.net>
Sat, 13 Feb 2021 21:29:59 +0000 (22:29 +0100)
cgilite/common.css [new file with mode: 0644]
cgilite/session.sh
cgilite/storage.sh

diff --git a/cgilite/common.css b/cgilite/common.css
new file mode 100644 (file)
index 0000000..9e72c16
--- /dev/null
@@ -0,0 +1,128 @@
+/* ======= GENERIC HTML STYLES ======= */
+
+* {
+  box-sizing: border-box;
+  position: relative;
+  font: inherit;
+  text-decoration: inherit;
+  color: inherit; background: transparent;
+  max-width: 100%;
+  margin: 0; padding: 0;
+  border: none;
+}
+
+body {
+  font: normal normal normal medium/1.5em sans-serif;
+  color: #000; background: #FFF;
+}
+
+ul, ol, dl, table, p { margin-bottom: .5em; }
+
+a {
+  font-style: italic;
+  text-decoration: underline;
+  color: #068;
+}
+a.button {
+  font-style: inherit;
+  text-decoration: inherit;
+  color: inherit;
+}
+
+sup { vertical-align: super; }
+sub { vertical-align: sub; }
+small { font-size: .75em; }
+big   { font-size: 1.25em; }
+strike, del, s { text-decoration: line-through; }
+u {text-decoration: underline; }
+i, em { font-style: italic; }
+b, strong { font-weight: bolder; }
+tt, code, var, samp, kbd { font-family: monospace; }
+kbd { font-style: italic; }
+
+ul, ol { margin-left: 1.125em; }
+dl dt { font-weight: bolder; }
+table th { font-weight: bold; }
+
+h1, h2, h3 {
+  font-weight: bold;
+  margin-top: .75em;
+  margin-bottom: .5em;
+}
+
+h4, h5, h6, form legend {
+  font-weight: bolder;
+  margin-bottom: .25em;
+}
+
+h1 { font-size: 1.5em; }
+h2 { font-size: 1.125em; }
+
+select, input, button, textarea, a.button {
+  display: inline-block;
+  background-color: #FFF;
+  border: .5pt solid;
+  padding: .25em .75em;
+  vertical-align: text-bottom;
+  border: .5pt solid #000;
+  border-radius: 2pt;
+}
+select { padding: .375em 0; }
+
+input[type=radio], input[type=checkbox] {
+  vertical-align: baseline;
+}
+input[type=number] { text-align: right; padding-right: 0; }
+
+button, input[type=button], a.button {
+  box-shadow: .125em .125em .25em;
+  cursor: pointer;
+}
+input[type=radio], input[type=checkbox], label[for] {
+  cursor: pointer;
+}
+
+label { margin-right: .75em; }
+input + label {
+  margin-left: .375em;
+}
+
+/* ======= End Generic Styles ======= */
+
+/* ======= Common Styles ======= */
+
+*[tooltip]:hover:after {
+  display: block;
+  position: absolute;
+  bottom: -100%; left: 50%; transform: translate(-50%, 0);
+  content: attr(tooltip);
+  padding: .5em;
+  background-color: #FFC;
+  color: #000;
+  border: .5pt solid;
+  z-index: 1;
+}
+
+input[type=radio].tab { display: none; }
+input[type=radio].tab + label {
+  display: table-cell;
+  padding: .5em 1em;
+  background-color: #EEE;
+  border: .5pt solid;
+}
+input[type=radio].tab:checked + label {
+  background-color: #FFF;
+  border-bottom: none;
+  box-shadow: .125em -.125em .125em #888;
+  z-index: 1;
+}
+input[type=radio].tab ~ *.tab {
+  display: none;
+  width: 100%;
+  margin-top: -.5pt; padding: .25em .75em;
+  border: .5pt solid;
+  border-radius: 0;
+  box-shadow: .125em .125em .125em #888;
+}
+
+/* ======= End Common Styles ======= */
index 0a2a2e8b6583ad95c1d95735de392f9d64e35615..b52ac0a5cc6fab71ba8a7926c27ac692a5c867de 100755 (executable)
@@ -25,10 +25,13 @@ slopecode(){
 }
 
 session_mac(){
+  local info
+  [ $# -eq 0 ] && info="$(cat)" || info="$*"
+
   if which openssl >/dev/null; then
-    openssl dgst -sha1 -hmac "$(server_key)" -binary |slopecode
+    printf %s "$info" |openssl dgst -sha1 -hmac "$(server_key)" -binary |slopecode
   else
-    { cat; server_key; } |sha256sum |cut -d\  -f1
+    { printf %s "$info"; server_key; } |sha256sum |cut -d\  -f1
   fi
 }
 
@@ -55,20 +58,17 @@ checkid(){ grep -m 1 -xE '[0-9a-zA-Z:=]{16}'; }
 transid(){
   # transaction ID to modify a given file
   local file="$1"
-  { stat -c %F%i%n%N%s%Y "$file" 2>&-
-    printf %s "$SESSION_ID"
-  } | session_mac
+  session_mac "$(stat -c %F%i%n%N%s%Y "$file" 2>&-)" "$SESSION_ID"
 }
 
 update_session(){
-  local session sid time sig serverkey checksig
+  local session sid time sig checksig
 
-  IFS=- read -r sid time sig <<-END
+  read -r sid time sig <<-END
        $(POST session_key || COOKIE session)
        END
-  serverkey="$(server_key)"
   
-  checksig="$(printf %s "$sid" "$time" |session_mac)"
+  checksig="$(session_mac "$sid" "$time")"
   
   if ! [ "$checksig" = "$sig" \
     -a "$time" -ge "$_DATE" \
@@ -79,10 +79,27 @@ update_session(){
   fi
 
   time=$(( $_DATE + $SESSION_TIMEOUT ))
-  sig="$(printf %s "$sid" "$time" |session_mac)"
-  printf %s\\n "${sid}-${time}-${sig}"
+  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%%-*}"
+SESSION_ID="${SESSION_KEY%% *}"
+
+SESSION_BIND() {
+  local key="$1" value="$2"
+  SET_COOKIE session "$key"="${value} $(session_mac "$value" "$SESSION_ID")"
+}
+
+SESSION_VAR() {
+  local key="$1"
+  local value sig
+  value="$(COOKIE "$key")"
+  sig="${value##* }" value="${value% *}"
+  if [ "$sig" = "$(session_mac "$value" "$SESSION_ID")" ]; then
+    printf %s\\n "$value"
+  else
+    return 1
+  fi
+}
index 7f70e6480d6c89c8a32d3a9ee3fb68a5bfcc35b6..82d3d77b8edf9e34cb237aa685a8228b8fd0d150 100755 (executable)
@@ -29,18 +29,18 @@ LOCK(){
   lock="${1}.lock"
   timeout="${2-20}"
   if [ \! -w "${lock%/*}" ] || [ -e "$lock" -a \! -d "$lock" ]; then
-    printf 'Impossible to get lock: %s\n' "$lock" >&2
+    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
-      printf 'Overriding stale lock: %s\n' "$lock" >&2
+      debug "Overriding stale lock: $lock"
       break
     fi
     if [ $timeout -le 0 ]; then
-      printf 'Timeout while trying to get lock: %s\n' "$lock" >&2
+      debug "Timeout while trying to get lock: $lock"
       return 1
     fi
     timeout=$((timeout - 1))
@@ -56,31 +56,22 @@ RELEASE(){
   if [ "$(cat "$lock/pid")" = "$$" ]; then
     rm "$lock/pid"
     if ! rmdir "$lock"; then
-      printf 'Cannot remove tainted lock: %s\n' "$lock" >&2
+      debug "Cannot remove tainted lock: $lock"
       printf '%i\n' $$ >"${lock}/pid"
       return 1
     fi
     return 0
   else
-    printf 'Refusing to release foreign lock: %s\n' "$lock" >&2
+    debug "Refusing to release foreign lock: $lock"
     return 1
   fi
 }
 
-STRING='
-  s;\\;\\\\;g;
-  s;\n;\\n;g;
-  s;\t;\\t;g;
-  s;\r;\\r;g;
-  s;\+;\\+;g;
-  s; ;+;g;
-'
-
-STRING_OLD(){
-  { [ $# -eq 0 ] && cat || printf %s "$*"; } \
-  | sed -E ':X; $!{N;bX;}'"$STRING"
-}
-
+# STRING='
+#   s;\\;\\\\;g; s;\t;\\t;g;
+#   s;\n;\\n;g;  s;\r;\\r;g;
+#   s;\+;\\+;g;  s; ;+;g;
+# '
 STRING(){
   local in out=''
   [ $# -gt 0 ] && in="$*" || in="$(cat)"
@@ -96,7 +87,6 @@ STRING(){
   printf '%s' "$out"
 }
 
-
 UNSTRING='
   :UNSTRING_X
   s;((^|[^\\])(\\\\)*)\\n;\1\n;g;
@@ -107,10 +97,6 @@ UNSTRING='
   s;((^|[^\\])(\\\\)*)\\\+;\1+;g;
   s;\\\\;\\;g;
 '
-UNSTRING_OLD(){
-  { [ $# -eq 0 ] && cat || printf %s "$*"; } \
-  | sed -E "$UNSTRING"
-}
 UNSTRING(){
   local in out=''
   [ $# -gt 0 ] && in="$*" || in="$(cat)"
@@ -127,3 +113,95 @@ UNSTRING(){
   printf '%s' "$out"
 }
 
+DBM() {
+  local file="$1" cmd="$2"
+  local k v key value
+  shift 2;
+
+  case "$cmd" in
+    check|contains)
+      key="$(STRING "$1")"
+      while read -r k v; do if [ "$k" = "$key" ]; then
+        return 0
+      fi; done <"$file" 2>&-
+      return 1
+      ;;
+    get)
+      key="$(STRING "$1")"
+      while read -r k v; do if [ "$k" = "$key" ]; then
+        UNSTRING "$v"
+        return 0
+      fi; done <"$file" 2>&-
+      return 1
+      ;;
+    set|store)
+      key="$(STRING "$1")" value="$(STRING "$2")"
+      LOCK "$file" || return 1
+      { while read -r k v; do
+          [ "$k" = "$key" ] || printf '%s\t%s\n' "$k" "$v"
+        done <"$file" 2>&-
+        printf '%s\t%s\n' "$key" "$value"
+      } >"${file}.$$.tmp"
+      mv "${file}.$$.tmp" "${file}"
+      RELEASE "$file"
+      return 0
+      ;;
+    add|insert)
+      k="$1" key="$(STRING "$1")" value="$(STRING "$2")"
+      LOCK "$file" || return 1
+      if DBM "$file" check "$k"; then
+        RELEASE "$file"
+        return 1
+      else
+        printf '%s\t%s\n' "$key" "$value" >>"${file}"
+        RELEASE "$file"
+        return 0
+      fi
+      ;;
+    update|replace)
+      k="$1" key="$(STRING "$1")" value="$(STRING "$2")"
+      LOCK "$file" || return 1
+      if ! DBM check "$k"; then
+        RELEASE "$file"
+        return 1
+      fi
+      { while read -r k v; do
+          [ "$k" = "$key" ] \
+          && printf '%s\t%s\n' "$key" "$value" \
+          || printf '%s\t%s\n' "$k" "$v"
+        done <"$file" 2>&-
+      } >"${file}.$$.tmp"
+      mv "${file}.$$.tmp" "${file}"
+      RELEASE "$file"
+      return 0
+      ;;
+    append)
+      key="$(STRING "$1")" value="$(STRING "$2")"
+      LOCK "$file" || return 1
+      if ! DBM check "$1"; then
+        RELEASE "$file"
+        return 1
+      fi
+      { while read -r k v; do
+          [ "$k" = "$key" ] \
+          && printf '%s\t%s\n' "$key" "$v$value" \
+          || printf '%s\t%s\n' "$k" "$v"
+        done <"$file" 2>&-
+      } >"${file}.$$.tmp"
+      mv "${file}.$$.tmp" "${file}"
+      RELEASE "$file"
+      return 0
+      ;;
+    delete|remove)
+      key="$(STRING "$1")"
+      LOCK "$file" || return 1
+      { while read -r k v; do
+          [ "$k" = "$key" ] || printf '%s\t%s\n' "$k" "$v"
+        done <"$file" 2>&-
+      } >"${file}.$$.tmp"
+      mv "${file}.$$.tmp" "${file}"
+      RELEASE "$file"
+      return 0
+      ;;
+  esac
+}