Index: misc-stml.scm ================================================================== --- misc-stml.scm +++ misc-stml.scm @@ -103,11 +103,14 @@ (cdr tail) newresult (car argtail) (cdr argtail))))))))) -;; random string stuff +;;====================================================================== +;; M I S C S T R I N G S T U F F +;;====================================================================== + (define (s:string-downcase str) (if (string? str) (string-translate str "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz") str)) @@ -135,11 +138,11 @@ (c:crypt pw (or s (c:crypt-gensalt)))) (define (s:password-match? password crypted) (let* ((salt (substring crypted 0 2)) (pcrypted (s:crypt-passwd password salt))) - (s:log "INFO: pcrypted=" pcrypted " crypted=" crypted) + ;; (s:log "INFO: pcrypted=" pcrypted " crypted=" crypted) (and (string? password) (string? pcrypted) (string=? pcrypted crypted)))) ;; (read-line (open-input-pipe "echo foo | mkpasswd -S ab -s")) Index: setup.scm ================================================================== --- setup.scm +++ setup.scm @@ -92,10 +92,70 @@ (define s:session-var-delete! s:session-var-del!) ;; utility to get all vars as hash table (define (s:session-get-sessionvars) (sdat-get-sessionvars s:session)) + +;; to obscure and indirect database ids use one time keys +;; +;; (s:get-key 'n 1) => "n99e1882" n=number 99e is the week number since 1970, remainder is random +;; (s:key->val "n1882") => 1 +;; +;; first letter is a type: n=number, s=string, b=boolean +(define (s:get-key key-type val) + (let ((mkrandstr (lambda (innum)(number->string (random innum) 16))) + (week (number->string (quotient (current-seconds) (* 7 24 60 60)) 16))) + (let loop ((siz 1000) + (key (conc key-type week (mkrandstr 100))) + (num 0)) + (if (s:session-var-get key) ;; have a collision + (loop (cond ;; in the unlikey event we have trouble getting a new var, keep increasing the size of the number + ((< num 50) 100) + ((< num 100) 1000) + ((< num 200) 10000) + ((< num 300) 100000) + ((< num 400) 1000000) ;; can't imagine needing to get here. remember that this is for a single user + (else 100000000)) + (conc key-type (mkrandstr siz)) + (+ num 1)) + (begin + (s:session-var-set! key val) + key))))) + +;; given a key Xnnnn, look up the stored value and convert it appropriately, then +;; destroy the stored session var +;; +(define (s:key->val key) + (let ((val (s:session-var-get key)) + (typ (string->symbol (substring key 0 1)))) + (if val + (begin + (s:session-var-del! key) + ;; we take this opportunity to clean up old keyed session vars + ;; if more than 100 vars, remove all that are over 1-2 weeks old + ;(s:cleanup-session-vars) + (case typ + ((n)(string->number val)) + ((s) val) + (else val))) + val))) + +;; clean up session vars +;; +(define (s:cleanup-session-vars) + (let* ((session-vars (hash-table-keys (s:session-get-sessionvars))) + (week-num (quotient (current-seconds) (* 7 24 60 60))) + (week (number->string week-num 16))) + (if (> (length session-vars) 100) + (for-each + (lambda (var) + (if (> (string-length var) 5) ;; can't have keyed values with keys less than 5 characters long + (let ((var-week (string->number (substring var 1 4) 16))) + (if (and var-week + (>= (- week-num var-week) 2)) + (s:session-var-del! var))))) + session-vars)))) ;; inputs ;; ;; param: (dtype [tag1 tag2 ...]) ;; dtype: