def do_request(SRPsession, req, do_network, db_server):
    SRPKsession_b64, sid_b64 = SRPsession
    enc1_b64,mac1_b64,enc2_b64,mac2_b64 = make_session_keys(SRPKsession_b64)
    msg = client_create_request(req, enc1_b64, mac1_b64, sid_b64)
    rx = do_network(db_server, msg)
    return client_process_response(rx, enc2_b64, mac2_b64)
 def receive_request(self, tx):
     # HTTP body is utf8(json(PIECES))
     pieces = json.loads(tx.decode("utf-8"))
     if pieces[0] == "magic-init":
         # PIECES = ["magic-init", email, b64(SRPv)]
         # reponse: "ok"
         print "MAGIC"
         email, SRPverifier_b64 = pieces[1:3]
         self.SRPverifier_b64[email] = SRPverifier_b64
         return "ok"
     if pieces[0] == "srp-1":
         # PIECES = ["srp-1", b64(sessionid), email, b64(A)]
         # response: utf8(json(["ok", b64(s), b64(B)]))
         sid_b64, email, A_b64 = pieces[1:4]
         if sid_b64 in self.verifiers or sid_b64 in self.sessions:
             raise Oops("sessionid already claimed")
         salt = ""
         vkey = b64decode(self.SRPverifier_b64[email])
         v = srp.Verifier(email.encode("utf-8"), salt,
                          vkey, b64decode(A_b64),
                          hash_alg=srp.SHA256)
         self.verifiers[sid_b64] = (v, email)
         s,B = v.get_challenge()
         if s is None or B is None:
             raise Oops("SRP rejected (A)")
         resp = ["ok", b64encode(s), b64encode(B)]
         return json.dumps(resp).encode("utf-8")
     if pieces[0] == "srp-2":
         # PIECES = ["srp-2", b64(sessionid), b64(M)]
         # response: utf8(json(["ok", b64(HAMK)]))
         sid_b64, M_b64 = pieces[1:3]
         if sid_b64 not in self.verifiers:
             raise Oops("no such session")
         if sid_b64 in self.sessions:
             raise Oops("sessionid already claimed")
         (v,email) = self.verifiers.pop(sid_b64)
         HAMK = v.verify_session(b64decode(M_b64))
         if HAMK is None:
             raise Oops("SRP rejected (M)")
         if not v.authenticated():
             raise Oops("SRP rejected")
         k_b64 = b64encode(v.get_session_key())
         self.sessions[sid_b64] = (k_b64, email)
         resp = ["ok", b64encode(HAMK)]
         return json.dumps(resp).encode("utf-8")
     if pieces[0] == "encrypted-request":
         # PIECES = ["encrypted-request", b64(sessionid), b64(encreqdata)]
         # reqdata = utf8(json([REQ]))
         # response = b64(enc(utf8(json(RESP)))
         sid_b64, enc_req_b64 = (pieces[1], pieces[2])
         if sid_b64 not in self.sessions:
             raise Oops("no such session")
         # We use very short-lived sessions for now: just one request.
         # TODO: need to time out old sessions, say after 5 minutes.
         k_b64,email = self.sessions.pop(sid_b64)
         (enc1_b64,mac1_b64,enc2_b64,mac2_b64) = make_session_keys(k_b64)
         rd_b64 = decrypt(enc1_b64, mac1_b64, enc_req_b64)
         req = json.loads(b64decode(rd_b64).decode("utf-8"))
         response = self.process_request(email, req)
         response_data_b64 = b64encode(json.dumps(response).encode("utf-8"))
         rx_b64 = encrypt_and_mac(enc2_b64, mac2_b64, response_data_b64)
         return rx_b64
     print "bad request", pieces
     raise Oops("bad request")