From b9d3701a99758bc8e6f9f981383524e0d3d87ff3 Mon Sep 17 00:00:00 2001 From: David Florness Date: Sat, 7 Mar 2020 14:25:13 -0700 Subject: [PATCH] Use tokens to ensure HTTP requests come from registered users --- bulletin.rkt | 60 ++++++++++++++++++++++++++++++++-------------------- client.rkt | 49 +++++++++++++++++++++--------------------- 2 files changed, 62 insertions(+), 47 deletions(-) diff --git a/bulletin.rkt b/bulletin.rkt index 9d05013..fe89e4b 100644 --- a/bulletin.rkt +++ b/bulletin.rkt @@ -2,6 +2,7 @@ (require racket/contract racket/list racket/match + racket/random racket/set racket/string) (require web-server/servlet @@ -9,9 +10,10 @@ json) (require simple-http) (require readline/readline) +(require (only-in openssl/sha1 bytes->hex-string)) (define state 'registering) -(define _peers (mutable-set)) +(define _peers (make-hasheq)) (define _commits (make-hash)) (define _outputs (make-hash)) (define _sums (make-hash)) @@ -70,11 +72,15 @@ [password (hash-ref params 'password)] [input (hash-ref params 'input)]) (if (auth username password) - (begin + (let* ([token (crypto-random-bytes 128)] + [token (bytes->hex-string token)]) (displayln (format "~a is voting! (~a)" username input)) - (set-add! _peers (hasheq 'input input - 'username username)) - (response/jsexpr empty)) + (hash-set! _peers (string->symbol token) + (hasheq 'input input + 'username username)) + ; send the token that the peer will use for further + ; authorization + (response/jsexpr token)) (response/jsexpr "Bad Login" #:code 400))) @@ -85,23 +91,25 @@ (define (peer-count request) (if (eq? state 'committing) - (response/jsexpr (set-count _peers)) + (response/jsexpr (hash-count _peers)) (response/jsexpr "Committing has not begun" #:code 403))) (define (commit request) (if (eq? state 'committing) - (let ([params (bytes->jsexpr (request-post-data/raw request))]) + (let* ([params (bytes->jsexpr (request-post-data/raw request))] + [peer (hash-ref _peers (string->symbol + (hash-ref params 'token)))]) (displayln params) - (hash-set! _commits (hash-ref params 'input) + (hash-set! _commits (hash-ref peer 'input) (hasheq 'p (hash-ref params 'p)) ; TODO: D polynomial ;; (hasheq 'd (hash-ref params 'd)) ) ; has everyone committed? (when (eqv? (hash-count _commits) - (set-count _peers)) + (hash-count _peers)) (transition)) (response/jsexpr empty)) (response/jsexpr "Not in the committing phase" @@ -109,7 +117,7 @@ (define (peers request) (if (eq? state 'voting) - (response/jsexpr (for/list ([v _peers]) + (response/jsexpr (for/list ([v (hash-values _peers)]) (hash-ref v 'input))) (response/jsexpr "Voting has not begun" @@ -117,17 +125,19 @@ (define (outputs request) (if (eq? state 'voting) - (begin + (let* ([params (bytes->jsexpr (request-post-data/raw request))] + ; ensure this is a registered peer + [peer (hash-ref _peers (string->symbol + (hash-ref params 'token)))]) ; TODO: check validity of inputs - (let ([params (bytes->jsexpr (request-post-data/raw request))]) - (for ([(p v) params]) - (hash-update! _outputs - (symbol->string p) - (λ (l) (cons v l)) empty))) + (for ([(p v) (hash-ref params 'outputs)]) + (hash-update! _outputs + (symbol->string p) + (λ (l) (cons v l)) empty)) ; has everyone submitted their outputs? (when (for/and ([(p v) _outputs]) (eqv? (length v) - (set-count _peers))) + (hash-count _peers))) (transition)) (response/jsexpr empty)) (response/jsexpr @@ -136,9 +146,11 @@ (define (_values request) (if (eq? state 'summing) - (let ([input (hash-ref (bytes->jsexpr (request-post-data/raw request)) 'input)]) + (let* ([params (bytes->jsexpr (request-post-data/raw request))] + [peer (hash-ref _peers (string->symbol + (hash-ref params 'token)))]) (response/jsexpr - (hash-ref _outputs input))) + (hash-ref _outputs (hash-ref peer 'input)))) (response/jsexpr "This election is not in the summing phase" #:code 403))) @@ -146,8 +158,10 @@ (define (sum request) (if (eq? state 'summing) (let* ([params (bytes->jsexpr (request-post-data/raw request))] - [input (string->symbol (hash-ref params 'input))] - [sum (hash-ref params 'sum)]) + [peer (hash-ref _peers (string->symbol + (hash-ref params 'token)))] + [input (string->symbol (hash-ref peer 'input))] + [sum (hash-ref params 'sum)]) (hash-set! _sums input sum) (response/jsexpr empty)) @@ -157,7 +171,7 @@ (define (sums request) (if (eq? (length (hash-keys _sums)) - (set-count _peers)) + (hash-count _peers)) (response/jsexpr _sums) (response/jsexpr @@ -217,7 +231,7 @@ ['cands (displayln (hash-ref election->candidates election))] ['peers - (displayln _peers)])] + (displayln (hash-values _peers))])] ['set (match (read sp) ['election (let ([election (read sp)]) (election-set! election))] diff --git a/client.rkt b/client.rkt index c8b40d2..bd56619 100644 --- a/client.rkt +++ b/client.rkt @@ -66,20 +66,21 @@ (define bulletin (update-port (update-host json-requester "localhost") 1984)) - (void - (let ([username (readline "Username: ")] - [password (get-pass "Password: ")]) - (with-handlers ([exn:fail:network:http:error? - (λ ([ex : exn:fail:network:http:error]) - (newline) - (displayln (format "Login refused: ~a" - (exn-message ex))) - (exit))]) - (post bulletin "/register" - #:data - (jsexpr->string (hasheq 'input (integer->hex-string point) - 'username username - 'password password)))))) + (define token + (let ([username (readline "Username: ")] + [password (get-pass "Password: ")]) + (with-handlers ([exn:fail:network:http:error? + (λ ([ex : exn:fail:network:http:error]) + (newline) + (displayln (format "Login refused: ~a" + (exn-message ex))) + (exit))]) + (json-response-body + (post bulletin "/register" + #:data + (jsexpr->string (hasheq 'input (integer->hex-string point) + 'username username + 'password password))))))) (displayln "retrieving candidates...") (define candidates (cast (json-response-body @@ -155,8 +156,7 @@ #:data (jsexpr->string (hasheq - 'input - (integer->hex-string point) + 'token token 'p (bytes->hex-string (merkle-node-hsh @@ -177,10 +177,13 @@ (post bulletin "/outputs" #:data (jsexpr->string - (for/hasheq : (Immutable-HashTable Symbol String) - ([p : Integer (cast peer-inputs (Listof Integer))]) - (values (string->symbol (integer->hex-string p)) - (integer->hex-string (poly p))))))) + (hasheq + 'token token + 'outputs + (for/hasheq : (Immutable-HashTable Symbol String) + ([p : Integer (cast peer-inputs (Listof Integer))]) + (values (string->symbol (integer->hex-string p)) + (integer->hex-string (poly p)))))))) (display "summing...") (void @@ -188,8 +191,7 @@ #:data (jsexpr->string (hasheq - 'input - (integer->hex-string point) + 'token token 'sum (integer->hex-string (foldl + 0 @@ -200,8 +202,7 @@ (post bulletin "/values" #:data (jsexpr->string - (hasheq 'input - (integer->hex-string point)))))) + (hasheq 'token token))))) (Listof String))))))))) (newline) -- 2.38.4