def run(self): received_obj=self.nobj snonce=self.snonce grasp.tprint("Got request for QUADS keys") if received_obj.dry: endit(snonce,"Dry run not supported") else: #unwrap pledge's request pledge_password = private_key.decrypt( received_obj.value[0], padding.OAEP( mgf=padding.MGF1(algorithm=hashes.SHA256()), algorithm=hashes.SHA256(), label=None)) if pledge_password != password: endit(snonce,"Incorrect password") else: #prepare pledge's public key pub_key = serialization.load_pem_public_key( received_obj.value[1], backend=default_backend() ) #prepare the QUADS keys chunk = cbor.dumps([key, iv]) grasp.tprint("Sending keys") #encrypt chunk received_obj.value = pub_key.encrypt( chunk, padding.OAEP( mgf=padding.MGF1(algorithm=hashes.SHA256()), algorithm=hashes.SHA256(), label=None)) grasp.ttprint("Sending",len(chunk),"bytes") #send keys as negotiation step err,temp,received_obj = grasp.negotiate_step(asa_nonce, snonce, received_obj, 1000) grasp.ttprint("Negotiation step gave:", err, temp, received_obj) if not err: # the other end signalled End/Accept grasp.tprint("Ended transfer") else: #other end rejected or loop count exhausted if err==grasp.errors.loopExhausted: # we need to signal the end endit(snonce, grasp.etext[err]) else: grasp.tprint("Failed:",grasp.etext[err])
def negotiate_step(asa_handle, shandle, obj, timeout): """ ############################################################## # negotiate_step(asa_handle, session_handle, objective, timeout) # # Continue negotiation session # # objective contains the next proffered value # Note that this instance of the objective # MUST be used in the subsequent negotiation calls because # it contains the loop count. # # timeout in milliseconds (None for default) # # return: exactly like request_negotiate ############################################################## """ e, s, r = grasp.negotiate_step(asa_handle, shandle, obj, timeout) if e == grasp.errors.ok: return e, s, r, None if e == grasp.errors.declined: return e, None, None, r return e, None, None, None
def run(self): answer = self.nobj snonce = self.snonce try: answer.value = cbor.loads(answer.value) grasp.tprint("CBOR value decoded") _cbor = True except: _cbor = False grasp.ttprint("listened, answer", answer.name, answer.value) grasp.tprint("Got request for", answer.value[0], answer.value[1]) if answer.dry: grasp.tprint("Dry run") result = True reason = None if answer.value[0] != "NZD": endit(snonce, "Invalid currency") elif answer.value[1] > reserves / 2: #other end wants too much, we need to negotiate proffer = int(reserves / 2) step = 1 concluded = False grasp.tprint("Starting negotiation") while not concluded: #proffer some resource grasp.tprint("Offering NZD", proffer) answer.value[1] = proffer if _cbor: answer.value = cbor.dumps(answer.value) err, temp, answer = grasp.negotiate_step( asa_nonce, snonce, answer, 1000) grasp.ttprint("Step", step, "gave:", err, temp, answer) step += 1 if (not err) and temp == None: concluded = True grasp.tprint("Negotiation succeeded") elif not err: try: answer.value = cbor.loads(answer.value) grasp.tprint("CBOR value decoded") except: pass grasp.tprint("Loop count", answer.loop_count, "request", answer.value[1]) #maybe wait (for no particular reason) if grasp._prng.randint(1, 10) % 2: err1 = grasp.negotiate_wait(asa_nonce, snonce, wt) grasp.tprint("Tried wait:", grasp.etext[err1]) time.sleep( 10 ) # if wt<10000 this tests anomaly handling by the peer grasp.tprint("Woke up") if proffer < 0.6 * reserves: proffer += 10 if proffer > answer.value[1]: proffer = answer.value[ 1] - 1 #always be a little mean else: #we don't have enough resource, we will reject result = False #randomly choose English or Russian error message if reserves % 2: reason = "Insufficient funds" else: reason = u"Недостаточно средств" endit(snonce, reason) concluded = True else: #other end rejected or loop count exhausted concluded = True result = False if err == grasp.errors.loopExhausted: # we need to signal the end endit(snonce, grasp.etext[err]) elif err == grasp.errors.declined and answer != "": grasp.tprint("Declined:", answer) else: grasp.tprint("Failed:", grasp.etext[err]) #end of negotiation loop pass #out of negotiation loop else: #we can accept the initially requested value grasp.tprint("Request accepted") err = grasp.end_negotiate(asa_nonce, snonce, True) if err: grasp.tprint("end_negotiate error:", grasp.etext[err])
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
def run(self): answer=self.nobj snonce=self.snonce answer.value, _cbor = detag(answer.value) if _cbor: grasp.tprint("CBOR value decoded") grasp.tprint("Got request") if answer.dry: endit(snonce,"Dry run not supported") return # Check format of request & extract fields try: req = answer.value.get("@rfcXXXX") except: req = None if not req: endit(snonce,"Not RFCXXXX format") return grasp.tprint(req) sel = req.get(cp.srv_element) if not sel: endit(snonce,"No service element") return msg_type = sel.get(cp.msg_type) if msg_type != cp.describe_request: endit(snonce,"Not describe_request") return srv_name = sel.get(cp.service) if not srv_name: endit(snonce,"No service name") return dom_name = sel.get(cp.domain) if not dom_name: endit(snonce,"No domain name") return # Construct DNS name dns_name = "_"+srv_name+"."+dom_name if dns_name[-1] != ".": dns_name += "." #Look for PTR record first found_something = False broken = False a = resolve(dns_name,'PTR') for r in a: found_something = True #extract the instance name raw_name = str(r) #decode Unicode escapes fixed_name = fix_string(raw_name) #remove bogus escapes name = fixed_name.replace("\\","") grasp.tprint("Got PTR name:",name) grasp.ttprint("Raw name:",raw_name) if name[-len(dns_name):] == dns_name: inst_name = name[0:-len(dns_name)-1] else: inst_name = name grasp.tprint("Instance name", inst_name) #start new reply element relement = new_relement() grasp.ttprint("Answer is", answer) relement[cp.outer][cp.sender_loop_count] = answer.loop_count relement[cp.outer][cp.srv_element][cp.instance] = inst_name relement[cp.outer][cp.srv_element][cp.service] = srv_name relement[cp.outer][cp.srv_element][cp.domain] = dom_name #look for other records a = resolve(fixed_name,'SRV') for r in a: grasp.ttprint("Got SRV", str(r)) #parse SRV record to extract the fields priority,weight,srv_port,srv_dom = str(r).split(' ') grasp.ttprint("Got SRV domain", srv_dom) relement[cp.outer][cp.srv_element][cp.priority] = int(priority) relement[cp.outer][cp.srv_element][cp.weight] = int(weight) srv_port = int(srv_port) #look for address records & build locators loc_l = [] a = resolve(srv_dom,'AAAA') for r in a: grasp.ttprint("Got AAAA", str(r)) srv_addr = ipaddress.IPv6Address(r) loc = [grasp.O_IPv6_LOCATOR,srv_addr.packed,17,srv_port] loc_l.append(["Internet", loc]) a = resolve(srv_dom,'A') for r in a: grasp.ttprint("Got A", str(r)) srv_addr = ipaddress.IPv4Address(r) loc = [grasp.O_IPv4_LOCATOR,srv_addr.packed,17,srv_port] loc_l.append(["Internet", loc]) loc_l.append(["Internet",[grasp.O_FQDN_LOCATOR,srv_dom,17,srv_port]]) #add locators to reply relement[cp.outer][cp.srv_element][cp.clocator] = loc_l a = resolve(name,'TXT') for r in a: grasp.tprint("Got TXT", r) #Note that TXT records may include quotes try: k,v = str(r).split(' ') if k[0]=='"': k=k[1:-1] if v[0]=='"': v=v[1:-1] grasp.ttprint("kv",k,v) relement[cp.outer][cp.srv_element][cp.kvps] = {k:v} except: grasp.ttprint("Couldn't split", str(r)) pass # The relement is now complete, send it as next negotiation step grasp.tprint("Reply step", relement) answer.value = relement if _cbor: answer.value=cbor.dumps(answer.value) #send reply as negotiation step err,temp,answer = grasp.negotiate_step(asa_nonce, snonce, answer, 1000) grasp.ttprint("Negotiation step gave:", err, temp, answer) if (not err) and temp==None: grasp.tprint("Reply step succeeded") elif not err: answer.value, _ = detag(answer.value) if _: grasp.tprint("CBOR value decoded") if answer.value !="ACK": grasp.tprint("Unexpected reply: loop count", answer.loop_count, "value",answer.value) endit(snonce, "Unexpected reply") broken = True break else: #other end rejected or loop count exhausted if err==grasp.errors.loopExhausted: # we need to signal the end endit(snonce, grasp.etext[err]) else: grasp.tprint("Failed:",grasp.etext[err]) broken = True break #Sent all relements if broken: return if not found_something: #NXDOMAIN endit(snonce, "Service not found") else: err = grasp.end_negotiate(asa_nonce, snonce, True) if err: grasp.tprint("end_negotiate error:",grasp.etext[err])
def run(self): nobj = self.nobj snonce = self.snonce try: nobj.value = cbor.loads(nobj.value) grasp.tprint("CBOR value decoded") _cbor = True except: _cbor = False req_ipv = nobj.value[ipv] #req_PD = nobj.value[PD] req_plen = nobj.value[lgth] if len(nobj.value) == lgth + 1: nobj.value.append(None) #grasp.tprint("Got request for IPv"+str(req_ipv)+"; PD=", req_PD, "length=", req_plen) grasp.tprint("Got request for IPv" + str(req_ipv) + "; length=", req_plen) if nobj.dry: grasp.tprint("Dry run (not handled by this implementation)") result = True reason = None if len(ppool) == 0: endit(snonce, "Prefix pool empty") elif req_ipv == 6: if req_plen < 32 or req_plen > subnet_max: endit(snonce, "Prefix length out of range") else: pref = get_from_pool(req_plen) if not pref: #other end wants too much, we try to make an offer while (not pref) and (req_plen < subnet_max): req_plen += 1 pref = get_from_pool(req_plen) if pref: nobj.value = [6, req_plen, pref] #nobj.value = [6, False, req_plen, pref] grasp.tprint("Starting negotiation") #we are offering the shortest prefix we can, so no #negotiation loop can happen grasp.tprint("Offering", prefstr(req_plen, pref)) if _cbor: nobj.value = cbor.dumps(nobj.value) err, temp, nobj = grasp.negotiate_step( asa_nonce, snonce, nobj, 1000) grasp.ttprint("Step gave:", err, temp, nobj) if (not err) and temp == None: grasp.tprint("Negotiation succeeded") elif not err: #we don't have enough resource, we will reject insert_pool(req_plen, pref) endit(snonce, "Insufficient resource") else: #other end rejected or loop count exhausted insert_pool(req_plen, pref) if err == grasp.errors.loopExhausted: # we need to signal the end endit(snonce, "Loop count exhausted") else: grasp.tprint("Failed:", grasp.etext[err]) #end of negotiation else: #got nothing suitable from pool endit(snonce, "No prefix available") elif req_ipv == 4: if req_plen < 16 or req_plen > 32: endit(snonce, "Prefix length out of range") else: pref = get4_from_pool(req_plen) if pref: nobj.value = [4, req_plen, pref[12:]] #nobj.value = [4, False, req_plen, pref[12:]] grasp.tprint("Starting negotiation") #we are offering the shortest prefix we can, so no #negotiation loop can happen grasp.tprint("Offering", pref4str(req_plen, pref[12:])) if _cbor: nobj.value = cbor.dumps(nobj.value) err, temp, nobj = grasp.negotiate_step( asa_nonce, snonce, nobj, 1000) grasp.ttprint("Step gave:", err, temp, nobj) if (not err) and temp == None: grasp.tprint("Negotiation succeeded") elif not err: #we don't have enough resource, we will reject insert_pool(req_plen, pref) endit(snonce, "Insufficient resource") else: #other end rejected or loop count exhausted insert_pool(req_plen, pref) if err == grasp.errors.loopExhausted: # we need to signal the end endit(snonce, "Loop count exhausted") else: grasp.tprint("Failed:", grasp.etext[err]) #end of negotiation else: #got nothing suitable from pool endit(snonce, "No prefix available")
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 run(self): global cheat_nonce reserves = grasp._prng.randint(100, 400) wt = grasp._prng.randint(15000, 40000) grasp.tprint("Reserves: $", reserves, "wait:", wt) err, asa_nonce = grasp.register_asa("Neg1") #assume it worked obj = grasp.objective("EX2") obj.neg = True #obj.loop_count = 2 #for testing purposes grasp.register_obj(asa_nonce, obj) #assume it worked cheat_nonce = asa_nonce #pass the nonce to the other negotiator! #attempt to listen err, snonce, answer = grasp.listen_negotiate(asa_nonce, obj) if err: grasp.tprint("listen_negotiate error:", grasp.etext[err]) else: grasp.tprint("listened, answer", answer.name, answer.value) grasp.tprint("Source was", snonce.id_source) result = True reason = None concluded = False if answer.value[0] != "NZD": result = False reason = "Invalid currency" elif answer.value[1] > reserves / 2: answer.value = ["NZD", int(reserves / 2)] err, temp, answer2 = grasp.negotiate_step( asa_nonce, snonce, answer, 1000) grasp.tprint("Step1 gave:", err, temp, answer2) if (not err) and (not temp): concluded = True grasp.tprint("Negotiation succeeded", answer2.value) elif not err: err1 = grasp.negotiate_wait(asa_nonce, snonce, wt) grasp.tprint("Tried wait:", grasp.etext[err1]) time.sleep( 20) #note - if wt<20000 this tests anomaly handling grasp.tprint("Woke up") answer2.value = ["NZD", int(0.75 * reserves)] err2, temp, answer3 = grasp.negotiate_step( asa_nonce, snonce, answer2, 1000) grasp.tprint("Step2 gave:", err2, temp, answer3) if (not err2) and (not temp): concluded = True grasp.tprint("Negotiation succeeded", answer3.value) elif not err2: result = False if reserves % 2: reason = "Insufficient funds" else: reason = u"Недостаточно средств" else: #other end rejected concluded = True grasp.tprint("Peer reject2:", answer3) else: #other end rejected concluded = True grasp.tprint("Peer reject1:", answer2) else: #can accept the requested value pass if not concluded: err = grasp.end_negotiate(asa_nonce, snonce, result, reason=reason) if err: grasp.tprint("end_negotiate error:", grasp.etext[err]) grasp.tprint("Exit")
answer.value = cbor.loads(answer.value) except: pass grasp.tprint("Peer offered", answer.value[1]) proffer = int(0.9 * iwant) step = 1 if answer.value[1] < proffer: #need to negotiate answer.value[1] = proffer concluded = False while not concluded: grasp.tprint("Asking for", proffer) if _cbor: #CBORise the value answer.value = cbor.dumps(answer.value) err, temp, answer = grasp.negotiate_step( asa_nonce, snonce, answer, 1000) grasp.ttprint("Loop count", step, "gave:", err, temp, answer) if _cbor and (not err): try: answer.value = cbor.loads(answer.value) except: pass if (not err) and temp == None: grasp.tprint("Negotiation succeeded", answer.value) concluded = True elif not err: grasp.tprint("Loop count", answer.loop_count, "offered", answer.value[1]) step += 1 proffer = int(0.9 * proffer) if answer.value[1] >= proffer:
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 run(self): requested_obj = self.nobj snonce = self.snonce requested_obj.value, _cbor = detag(requested_obj.value) if _cbor: grasp.tprint("CBOR value decoded") grasp.tprint("Got request for", requested_obj.value) if requested_obj.dry: endit(snonce, "Dry run not supported") else: try: file = open(requested_obj.value, "rb") except Exception as e: grasp.tprint("File open error") endit(snonce, str(e)) return chunk = True grasp.tprint("Starting transfer") while chunk: chunk = file.read(1024) grasp.ttprint("Sending", len(chunk), "bytes") requested_obj.value = chunk #bump the loop count for next chunk requested_obj.loop_count += 1 if _cbor: requested_obj.value = cbor.dumps(requested_obj.value) #send chunk as negotiation step err, temp, requested_obj = grasp.negotiate_step( asa_nonce, snonce, requested_obj, 1000) grasp.ttprint("Negotiation step gave:", err, temp, requested_obj) if (not err) and temp == None: # the other end signalled End/Accept grasp.tprint("Ended transfer") elif not err: requested_obj.value, _ = detag(requested_obj.value) if _: grasp.ttprint("CBOR value decoded") if (not len(chunk)) or (requested_obj.value != 'ACK'): # we got a reply after EOF, or a bad ACK grasp.tprint("Unexpected reply: loop count", requested_obj.loop_count, "value", requested_obj.value) endit(snonce, "Unexpected reply") break else: #other end rejected or loop count exhausted if err == grasp.errors.loopExhausted: # we need to signal the end endit(snonce, grasp.etext[err]) else: grasp.tprint("Failed:", grasp.etext[err]) break file.close()
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 run(self): answer = self.nobj snonce = self.snonce answer.value, _cbor = detag(answer.value) if _cbor: grasp.tprint("CBOR value decoded") grasp.tprint("Got request for", answer.value) if answer.dry: endit(snonce, "Dry run not supported") else: reply = [] reply_size = 0 #Look for PTR record first a = resolve(answer.value, 'PTR') for r in a: #extract the name raw_name = str(r) #decode Unicode escapes fixed_name = fix_string(raw_name) #remove bogus escapes name = fixed_name.replace("\\", "") grasp.tprint("Got PTR name:", name) grasp.ttprint("Raw name:", raw_name) #remember where we are in the list reply_mark = len(reply) #add RR to reply reply.append('PTR ' + name) #look for other records a = resolve(fixed_name, 'SRV') for r in a: srv_reply = [] grasp.ttprint("Got SRV", str(r)) srv_reply.append('SRV ' + str(r)) #parse SRV record to extract the domain _, _, _, domain = str(r).split(' ') grasp.ttprint("Got domain", domain) #look for address records a = resolve(domain, 'AAAA') for r in a: grasp.ttprint("Got AAAA", str(r)) srv_reply.append('AAAA ' + str(r)) a = resolve(domain, 'A') for r in a: grasp.ttprint("Got A", str(r)) srv_reply.append('A ' + str(r)) #add RRs to reply reply.append(srv_reply) a = resolve(name, 'TXT') for r in a: grasp.ttprint("Got TXT", str(r)) #Note that TXT records may include quotes reply.append('TXT ' + str(r)) #fragment before reaching 2000 bytes _l = len(cbor.dumps(reply)) if _l > reply_size + 1900: #getting big, mark to fragment before previous PTR grasp.tprint("Fragmenting before", _l) reply_size += (_l + 5) reply.insert(reply_mark, 'MORE') #reply is now a (possibly empty) list of RRs if len(reply): grasp.tprint("Found", reply) else: reply = ['NXDOMAIN'] grasp.tprint("No record in DNS") #grasp.tprint("Object length",sys.getsizeof(reply),"bytes") #creply=cbor.dumps(reply) #grasp.tprint("CBOR length",len(creply),"bytes") while len(reply): if 'NXDOMAIN' in reply: piece = [] reply = [] elif 'MORE' in reply: grasp.tprint("Oversized reply fragmented") mx = reply.index('MORE') + 1 piece = reply[:mx] reply = reply[mx:] else: piece = reply reply = [] answer.value = piece if _cbor: answer.value = cbor.dumps(answer.value) #send reply as negotiation step err, temp, answer = grasp.negotiate_step( asa_nonce, snonce, answer, 1000) grasp.ttprint("Negotiation step gave:", err, temp, answer) if (not err) and temp == None: grasp.tprint("Reply step succeeded") elif not err: answer.value, _ = detag(answer.value) if _: grasp.tprint("CBOR value decoded") if not len(reply): grasp.tprint("Unexpected reply: loop count", answer.loop_count, "value", answer.value) endit(snonce, "Unexpected reply") else: #other end rejected or loop count exhausted reply = [] #to get us out of the loop if err == grasp.errors.loopExhausted: # we need to signal the end endit(snonce, grasp.etext[err]) else: grasp.tprint("Failed:", grasp.etext[err])