~edwargix/tallyard

b9d3701a99758bc8e6f9f981383524e0d3d87ff3 — David Florness 5 years ago 5b94216
Use tokens to ensure HTTP requests come from registered users
2 files changed, 62 insertions(+), 47 deletions(-)

M bulletin.rkt
M client.rkt
M bulletin.rkt => bulletin.rkt +37 -23
@@ 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))]

M client.rkt => client.rkt +25 -24
@@ 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)