def request_negotiate(asa_handle, obj, peer, timeout): """ ############################################################## # request_negotiate(asa_handle, obj, peer, timeout) # # Request negotiation session with a peer ASA. # # asa_handle identifies the calling ASA # # obj is a GRASP objective including the requested value # # The objective's loop_count value should be set to a suitable # value by the ASA. If not, the GRASP default will apply. # # peer is the target node, an asa_locator as returned by discover() # If peer is None, discovery is performed first. # # timeout in milliseconds (None for default) # # Launch in a new thread if asynchronous operation required. # # Four possible return conditions are possible: # # 1) return zero, None, objective, None # # The peer has agreed; the returned objective contains the agreed value. # # 2) return zero, session_handle, objective, None # # Negotiation continues. # # The returned objective contains the first value offered by the # negotiation peer. This instance of the objective MUST be used in # subsequent negotiation steps because it contains the loop count. # # The ASA MUST store the session_handle (an opaque Python object) # and use it in the subsequent negotiation steps. # # 3) return errors.declined, None, None, string # # The peer declined further negotiation, the string gives a reason # if provided by the peer. # # 4) For any non-zero errorcode except errors.declined: # return errorcode, None, None, None # # The negotiation failed, errorcode gives reason, # exponential backoff RECOMMENDED before retry. ############################################################## """ e, s, r = grasp.req_negotiate(asa_handle, obj, peer, timeout) if e == errors.ok: return e, s, r, None if e == errors.declined: return e, None, None, r return e, None, None, None
#discover a peer if failct > 3: failct = 0 grasp.tprint("Flushing EX3 discovery") _, ll = grasp.discover(asa_handle, obj3, 1000, flush = True) else: _, ll = grasp.discover(asa_handle, obj3, 1000) if ll==[]: grasp.tprint("Discovery failed") failct += 1 continue grasp.ttprint("Discovered locator", ll[0].locator) #attempt to negotiate grasp.tprint("Session starting") err, shandle, answer = grasp.req_negotiate(asa_handle, obj3, ll[0], None, noloop=True) if err == grasp.errors.noReply: #session is available err = False while not err: tweet = input("Your message:") err = grasp.gsend(asa_handle, shandle, tweet) if not err: err, reply = grasp.grecv(asa_handle, shandle, 60000) if not err: grasp.tprint("Peer replied:", reply) grasp.tprint("Send/recv error:",grasp.etext[err]) #all errors are fatal, the session is dead grasp.tprint("End of session") continue
def get_dns_info(dom): """Obtain and return all DNS-SD records for a domain""" global obj3 global failct #start of a negotiating session obj3.value = dom obj3.loop_count = 10 #allows for some fragmentation # As a random test, use CBOR (Tag 24) format for value (should work) if not grasp._prng.randint(0, 3): _cbor = True else: _cbor = False # As a random test, request dry run (should fail) if not grasp._prng.randint(0, 7): obj3.dry = True # random error for testing purposes else: obj3.dry = False grasp.tprint("Asking for", obj3.value, "; dry run", obj3.dry, "; Tag 24", _cbor) #discover a peer if failct > 3: failct = 0 grasp.tprint("Flushing", obj3.name, "discovery") _, ll = grasp.discover(asa_nonce, obj3, 1000, flush=True) else: _, ll = grasp.discover(asa_nonce, obj3, 1000) if ll == []: grasp.tprint("Discovery failed") failct += 1 return grasp.ttprint("Discovered locator", ll[0].locator) #attempt to negotiate if _cbor: #CBORise the value obj3.value = cbor.dumps(obj3.value) reply = [] err, snonce, answer = grasp.req_negotiate(asa_nonce, obj3, ll[0], None) if err: if err == grasp.errors.declined and answer != "": _e = answer else: _e = grasp.etext[err] grasp.tprint("req_negotiate error:", _e) failct += 1 grasp.tprint("Fail count", failct) time.sleep(5) #to calm things if there's a looping error elif (not err) and snonce: grasp.ttprint("requested, session_nonce:", snonce, "answer", answer) _found_cbor = False if _cbor: answer.value, _found_cbor = detag(answer.value) grasp.ttprint("Received reply", answer.value) if _cbor != _found_cbor: #Anomaly, get me out of here grasp.tprint("CBOR anomaly 1 - missing segment?") grasp.end_negotiate(asa_nonce, snonce, False, reason="CBOR anomaly 1 - missing segment?") elif not grasp._prng.randint(0, 7): ####################################################### # As a random test of robustness, send a bogus response answer.value = "rubbish" grasp.tprint("Sending rubbish") if _cbor: #CBORise the value answer.value = cbor.dumps(answer.value) err, temp, answer = grasp.negotiate_step(asa_nonce, snonce, answer, 1000) grasp.ttprint("Reply to rubbish:", err, temp, answer) _found_cbor = False if _cbor and (not err): answer.value, _found_cbor = detag(answer.value) if (not err) and temp == None: grasp.tprint("Unexpected answer:", answer.value) elif (not err) and _cbor != _found_cbor: grasp.tprint("CBOR anomaly 2 - missing segment?") elif not err: grasp.tprint("Loop count", answer.loop_count, "unexpected answer", answer.value) err = grasp.end_negotiate(asa_nonce, snonce, False, reason="Unexpected answer") if err: grasp.tprint("end_negotiate error:", grasp.etext[err]) else: #other end rejected if err == grasp.errors.declined and answer != "": _e = answer else: _e = grasp.etext[err] grasp.tprint("Peer reject:", _e) # End of random test of robustness ####################################################### else: #Received answer looping = True while looping: grasp.ttprint("Answer is", answer.value) if 'MORE' in answer.value: #need to go again reply += answer.value[:answer.value.index('MORE')] answer.value = "ACK" grasp.tprint("Sending ACK for more") if _cbor: #CBORise the value answer.value = cbor.dumps(answer.value) err, temp, answer = grasp.negotiate_step( asa_nonce, snonce, answer, 1000) if err: grasp.tprint("negotiate_step error:", grasp.etext[err]) looping = False elif _cbor: answer.value, _found_cbor = detag(answer.value) if _cbor != _found_cbor: #anomaly, get me out of here looping = False grasp.end_negotiate( asa_nonce, snonce, False, reason="CBOR anomaly - missing segment?") grasp.tprint("CBOR anomaly 3 - missing segment?") grasp.ttprint("Reply to ACK:", err, temp, answer) else: looping = False reply += answer.value err = grasp.end_negotiate(asa_nonce, snonce, True) if not err: if len(reply): grasp.tprint("Query succeeded", reply) else: grasp.tprint("Empty result") else: grasp.tprint("end_negotiate error:", grasp.etext[err]) else: #immediate end, strange grasp.tprint("Unexpected reply", answer.value) #end of a negotiating session time.sleep(5) #to keep things calm... return
#good one is still available peer = good_peer grasp.tprint("Trying previous peer") else: ## #cycle through peers ## if next_peer < len(ll): ## peer = ll[next_peer] ## next_peer += 1 ## else: ## peer = ll[0] ## next_peer = 1 #pick peer at random next_peer = grasp._prng.randint(0, len(ll) - 1) peer = ll[next_peer] grasp.tprint("Trying peer", next_peer, "out of", len(ll)) err, snonce, answer = grasp.req_negotiate(asa_nonce, want_obj, peer, 3000) if not err: if snonce: #we got an offer if answer.value[lgth] < want_p + 1: #acceptable grasp.end_negotiate(asa_nonce, snonce, True) insert_pool(answer.value[lgth], answer.value[pfx]) need = 0 good_peer = peer #cache this one grasp.tprint( "Obtained", prefstr(answer.value[lgth], answer.value[pfx])) else: #unacceptable grasp.end_negotiate(asa_nonce, snonce, False,
failct = 0 grasp.tprint("Flushing EX3 discovery") _, ll = grasp.discover(asa_nonce, obj3, 1000, flush=True) else: _, ll = grasp.discover(asa_nonce, obj3, 1000) if ll == []: grasp.tprint("Discovery failed") failct += 1 continue grasp.ttprint("Discovered locator", ll[0].locator) #attempt to negotiate grasp.tprint("Session starting") err, snonce, answer = grasp.req_negotiate(asa_nonce, obj3, ll[0], None, noloop=True) if err == grasp.errors.noReply: #session is available err = False while not err: tweet = input("Your message:") err = grasp.gsend(asa_nonce, snonce, tweet) if not err: err, reply = grasp.grecv(asa_nonce, snonce, 60000) if not err: grasp.tprint("Peer replied:", reply) grasp.tprint("Send/recv error:", grasp.etext[err]) #all errors are fatal, the session is dead
def run(self): global cheat_nonce iwant = grasp._prng.randint(10, 500) grasp.tprint("Asking for $", iwant) err, asa_nonce2 = grasp.register_asa("Neg2") #assume it worked obj = grasp.objective("EX2") obj.neg = True #obj.loop_count = 2 #for testing purposes while cheat_nonce == None: time.sleep( 1) #we should exit after neg1 has registered the objective asa_nonce = cheat_nonce #now we can pretend to own the objective grasp.tprint("Got nonce", asa_nonce) err, ll = grasp.discover(asa_nonce, obj, 5000) if ll == []: grasp.tprint("Discovery failed: exit") return grasp.tprint("Discovered locator", ll[0].locator) #attempt to negotiate obj.value = ["NZD", iwant] if not iwant % 7: obj.value = ["USD", iwant] # for testing purposes err, snonce, answer = grasp.req_negotiate(asa_nonce, obj, ll[0], None) if err: if err == grasp.errors.declined and answer != "": _t = answer else: _t = grasp.etext[err] grasp.tprint("req_negotiate error:", _t) elif (not err) and snonce: grasp.tprint("requested, session_nonce:", snonce, "answer", answer) if answer.value[1] < 0.75 * iwant: answer.value[1] = int(0.75 * iwant) err, temp, answer2 = grasp.negotiate_step( asa_nonce, snonce, answer, 1000) grasp.tprint("Step1 gave:", err, temp, answer2) if (not err) and (not temp): grasp.tprint("Negotiation succeeded", answer.value) elif not err: #not acceptable, try one more time answer2.value[1] = int(0.6 * iwant) #at random, throw an invalid format of message if not iwant % 3: grasp.tprint("Trying badmess") grasp._make_badmess = True err, temp, answer3 = grasp.negotiate_step( asa_nonce, snonce, answer2, 1000) grasp.tprint("Step2 gave:", err, temp, answer3) if (not err) and (not temp): grasp.tprint("Negotiation succeeded", answer3.value) elif (not err): #not acceptable err = grasp.end_negotiate(asa_nonce, snonce, False, reason="You are mean!") if err: grasp.tprint("end_negotiate error:", grasp.etext[err]) else: #other end rejected grasp.tprint("Peer reject:", answer3) else: #other end rejected grasp.tprint("Peer reject:", answer2) else: #acceptable answer err = grasp.end_negotiate(asa_nonce, snonce, True) if not err: grasp.tprint("Negotiation succeeded", answer.value) else: grasp.tprint("end_negotiate error:", grasp.etext[err]) else: #acceptable answer first time grasp.tprint("Negotiation succeeded", answer.value) grasp.tprint("Exit")
def get_dns_info(service, dom): """Obtain and return all DNS-SD records for a service and domain""" global obj3 global failct #start of a negotiating session obj3.loop_count = 20 #allows for some fragmentation obj3.dry = False #dry run not allowed req_elem = new_relement() req_elem[cp.outer][cp.sender_loop_count] = obj3.loop_count req_elem[cp.outer][cp.srv_element][cp.service] = service req_elem[cp.outer][cp.srv_element][cp.domain] = dom obj3.value = req_elem # As a random test, use CBOR (Tag 24) format for value (should work) if not grasp._prng.randint(0, 3): _cbor = True else: _cbor = False grasp.tprint("Asking for", obj3.value, "; Tag 24", _cbor) #discover a peer if failct > 3: failct = 0 grasp.tprint("Flushing", obj3.name, "discovery") _, ll = grasp.discover(asa_nonce, obj3, 1000, flush=True) else: _, ll = grasp.discover(asa_nonce, obj3, 1000) if ll == []: grasp.tprint("Discovery failed") failct += 1 return grasp.ttprint("Discovered locator", ll[0].locator) #attempt to negotiate if _cbor: #CBORise the value obj3.value = cbor.dumps(obj3.value) reply = [] err, snonce, answer = grasp.req_negotiate(asa_nonce, obj3, ll[0], None) if err: if err == grasp.errors.declined and answer != "": _e = answer else: _e = grasp.etext[err] grasp.tprint("req_negotiate error:", _e) failct += 1 grasp.tprint("Fail count", failct) time.sleep(5) #to calm things if there's a looping error elif (not err) and snonce: grasp.ttprint("requested, session_nonce:", snonce, "answer", answer) _found_cbor = False if _cbor: answer.value, _found_cbor = detag(answer.value) grasp.tprint("First reply:", prettify(answer.value)) if _cbor != _found_cbor: #Anomaly, get me out of here grasp.tprint("CBOR anomaly 1 - missing segment?") grasp.end_negotiate(asa_nonce, snonce, False, reason="CBOR anomaly 1 - missing segment?") else: #Received first answer looping = True while looping: #need to go again answer.value = "ACK" grasp.tprint("Sending ACK for more") answer.loop_count += 2 #allow an extra round trip if _cbor: #CBORise the value answer.value = cbor.dumps(answer.value) err, temp, answer = grasp.negotiate_step( asa_nonce, snonce, answer, 5000) if err: grasp.tprint("negotiate_step error:", grasp.etext[err]) looping = False elif not temp: #end of replies looping = False else: if _cbor: answer.value, _found_cbor = detag(answer.value) if _cbor != _found_cbor: #anomaly, get me out of here looping = False grasp.end_negotiate( asa_nonce, snonce, False, reason="CBOR anomaly 2 - missing segment?") grasp.tprint("CBOR anomaly 2 - missing segment?") return grasp.tprint("Next reply:", prettify(answer.value)) grasp.tprint("End of replies") else: #immediate end, strange grasp.tprint("Unexpected reply", answer.value) #end of a negotiating session time.sleep(5) #to keep things calm... return
def get_file(fn): """Get a single file""" global requested_obj global failct global directory #start of a negotiating session requested_obj.value = fn requested_obj.loop_count = 10 #allows for some fragmentation #prepare file path for result try: #strip C:/brian/docs for xfer from Windows to Linux _, fpath = fn.split("C:/brian/docs/") except: fpath = directory + fn grasp.tprint("Asking for", requested_obj.value) #discover a peer if failct > 3: failct = 0 grasp.tprint("Flushing", requested_obj.name, "discovery") _, ll = grasp.discover(asa_nonce, requested_obj, 1000, flush=True) else: _, ll = grasp.discover(asa_nonce, requested_obj, 1000) if ll == []: grasp.tprint("Discovery failed") failct += 1 return grasp.ttprint("Discovered locator", ll[0].locator) #attempt to negotiate reply = b'' err, snonce, received_obj = grasp.req_negotiate(asa_nonce, requested_obj, ll[0], 5000) if err: if err == grasp.errors.declined and received_obj != "": _e = received_obj else: _e = grasp.etext[err] grasp.tprint("req_negotiate error:", _e) failct += 1 grasp.tprint("Fail count", failct) elif (not err) and snonce: grasp.ttprint("requested, session_nonce:", snonce, "received_obj", received_obj) grasp.ttprint("Received reply", received_obj.value) looping = True first = True while looping: grasp.ttprint("received_obj is", received_obj.value) if first and (received_obj.value == b''): grasp.tprint("File not found") looping = False elif received_obj.value == b'': #got the last block looping = False file.close() err = grasp.end_negotiate(asa_nonce, snonce, True) if not err: grasp.tprint("Transfer succeeded") else: grasp.tprint("end_negotiate error:", grasp.etext[err]) elif len(received_obj.value): if first: file = open(fpath, "wb") grasp.tprint("Starting transfer") #write a block and go again file.write(received_obj.value) received_obj.value = "ACK" received_obj.loop_count += 1 grasp.ttprint("Sending ACK for more") err, temp, received_obj = grasp.negotiate_step( asa_nonce, snonce, received_obj, 1000) if err: if err == grasp.errors.declined and received_obj != "": _e = received_obj else: _e = grasp.etext[err] grasp.tprint("negotiate_step error:", _e) looping = False grasp.ttprint("Reply to ACK:", err, temp, received_obj) first = False else: #immediate end, strange grasp.tprint("Unexpected reply", received_obj.value) #end of a negotiating session time.sleep(5) #to keep things calm... return
def get_file(): """Get key file""" global keys_obj global failct global private_key #look for quadski err, results = grasp.get_flood(asa_nonce, flood_obj) if not err: # results contains all the unexpired tagged objectives # but really there should only be one... if results == []: grasp.tprint("Found no value for",flood_obj.name) time.sleep(10) #pause for something to change... return else: grasp.tprint("Found value for",flood_obj.name) # recover quadski's public key quadski_pub_key = serialization.load_pem_public_key( results[0].objective.value, backend=default_backend() ) else: grasp.tprint("get_flood failed", grasp.etext[err]) return #not this time #set up objective value ciphertext = quadski_pub_key.encrypt( password, padding.OAEP( mgf=padding.MGF1(algorithm=hashes.SHA256()), algorithm=hashes.SHA256(), label=None)) keys_obj.value = [ciphertext,pem] #start of negotiating session grasp.tprint("Asking for keys") #discover a peer if failct > 3: failct = 0 grasp.tprint("Flushing", keys_obj.name, "discovery") _, ll = grasp.discover(asa_nonce, keys_obj, 1000, flush = True) else: _, ll = grasp.discover(asa_nonce, keys_obj, 1000) if ll==[]: grasp.tprint("Discovery failed") failct += 1 return grasp.ttprint("Discovered locator", ll[0].locator) #attempt to negotiate err, snonce, received_obj = grasp.req_negotiate(asa_nonce, keys_obj, ll[0], 5000) if err: if err==grasp.errors.declined and received_obj!="": _e = received_obj else: _e = grasp.etext[err] grasp.tprint("Negotiation error:", _e) failct += 1 grasp.tprint("Fail count", failct) if _e == "Incorrect password": get_pass() return elif (not err) and snonce: grasp.ttprint("requested, session_nonce:",snonce,"received_obj",received_obj) grasp.ttprint("Received raw reply",received_obj.value) grasp.ttprint("received_obj is", received_obj.value) if received_obj.value == b'': grasp.tprint("Keys not found") else: grasp.ttprint("Starting transfer") #decrypt block plaintext = private_key.decrypt( received_obj.value, padding.OAEP( mgf=padding.MGF1(algorithm=hashes.SHA256()), algorithm=hashes.SHA256(), label=None)) keys = cbor.loads(plaintext) key = keys[0] iv = keys[1] file = open(r"quadsk.py","w") file.write("key="+str(key)+"\n") file.write("iv="+str(iv)+"\n") file.close() grasp.tprint("quadsk.py saved OK") err = grasp.end_negotiate(asa_nonce, snonce, True) if err: grasp.tprint("end_negotiate error:",grasp.etext[err]) else: #immediate end, strange grasp.tprint("Unexpected reply", received_obj.value) #end of a negotiating session time.sleep(10) #pause for something to change... return