keys.loadKeypair('config/id.yaml') except: print('Generating server keypair...') keys.createKeypair() keys.saveKeypair('config/id.yaml') keys.loadKnownHosts('config/knownhosts.yaml') keys.loadIncomingInvites('config/incoming_invites.ip') keys.loadOutgoingInvites('config/outgoing_invites.ip') router = PacketRouter(v6, inport, keys, passwd) router.connect(trackerAddr[0], trackerAddr[1]) tracker = TrackerClient(router) router.start() keypair = keys.getKeypair() pubkey = keypair.public invite = keys.generateInvite(inport, v6=v6) tracker.putInviteForPeer(encodeAddress((host, inport)), encode(invite.message)) endpoints = YamlMap('config/endpoints.yaml') for key in endpoints.values(): tracker.putPeerForEndpoint( key, [encode(pubkey.bytes), encodeAddress((host, inport))]) wait()
class DustmailReader: def __init__(self, router, endpoint): self.router=router self.endpoint=endpoint self.keys=router.keys self.maildir='spool/'+encode(endpoint.public.bytes) self.addressBook=YamlMap('config/dustmail-addressbook.yaml') self.done=Event() self.commandDone=Event() self.book=YamlMap('config/dustmail-addressbook.yaml') dustmailConfig=YamlMap('config/dustmail-config.yaml') try: destAddress=dustmailConfig['tracker'] except: entry=self.addInvite() destAddress=entry['tracker'] dustmailConfig['tracker']=destAddress dest, outport, v6=decodeAddress(destAddress) print('Registering with tracker...') self.tracker=TrackerClient(self.router, addr=(dest, outport)) host=getPublicIP(v6) inport=dustmailConfig['port'] self.tracker.putPeerForEndpoint(encode(self.endpoint.public.bytes), [encode(self.endpoint.public.bytes), encodeAddress((host,inport))]) invite=self.keys.generateInvite(inport, v6=v6) self.tracker.putInviteForPeer(encodeAddress((host, inport)), encode(invite.message)) self.trackback=self.router.getService('trackback') def start(self): print('-'*40) msgs=self.displayList() command=None while command!='x': command=input('> ').strip() try: num=int(command) self.displayMessage(msgs[num-1][1]) except: if command=='l': msgs=self.displayList() else: self.parseCommand(command) def displayList(self): # msgs=os.listdir(maildir) msgs=[] for file in glob.glob(self.maildir + '/*.*'): stats = os.stat(file) lastmod_date = time.localtime(stats[8]) date_file_tuple = lastmod_date, file msgs.append(date_file_tuple) if len(msgs)==0: print("No messages.") else: msgs.sort() msgs.reverse() for x in range(len(msgs)): date, fname=msgs[x] frm=fname.split('/')[-1].split('-')[0] modtime=time.strftime("%m/%d/%Y %I:%M%p",date) frmName=self.nameForPubkey(frm) if not frmName: frmName=frm print(str(x+1)+': '+frmName+' '+modtime) return msgs def nameForPubkey(self, pubkey): for name in self.book.keys(): key=self.book[name]['pubkey'] if key==pubkey: return name return None def displayMessage(self, fname): f=open(fname, 'r') msg=f.read() f.close() data=decode(msg) onion=OnionPacket() #print(onion) try: onion.decodeOnionPacket(self.endpoint, data) except: traceback.print_exc() #print(onion) print(onion.data.decode('ascii')) def parseCommand(self, command): self.commandDone.clear() if command=='x': self.commandDone.set() self.done.set() sys.exit(0) elif command=='a': self.addInvite() elif command=='i': self.makeInvite() elif command=='s': self.sendMessage() elif command=='?': self.printHelp() waitForEvent(self.commandDone) def addInvite(self): pf=input("Load invite from Paste or File [P/f]? ") if pf=='f': filename=input("Load invite from filename: ").strip() f=open(filename, 'rb') data=f.read() f.close() else: data=decode(input("Past invite: ")) passwd=input("Decrypt invite with password: "******"Name for this endpoint: ") try: entry=self.book[name] except: entry={} entry['pubkey']=encode(packet.pubkey) entry['tracker']=encodeAddress((invite.ip, invite.port)) self.book[name]=entry self.commandDone.set() return entry def makeInvite(self): self.trackback.setPutTrackerInviteCallback(self.gotInvite) self.tracker.getTrackerInvite() def gotInvite(self, invite): time.sleep(1) print() ps=input("Print, Save, or Email [P/s/e]? ") passwd=input("Encrypt invite with password: "******"Save invite to filename: ").strip() if filename!='': f=open(filename, 'wb') f.write(packet.packet) f.close() elif ps=='e': frm=input("Your email: ") to=input("Recipient email: ") name=input("Your name on DustMail: ") body=""" You have been invited to communicate with %s via DustMail. Use the following invite code: %s """ % (name, encode(packet.packet)) emailConfig=YamlMap('config/emailServer.yaml') try: smtpHost=emailConfig['smtpHost'] except: smtpHost=input("SMTP Host: ") emailConfig['smtpHost']=smtpHost notifier=Notifier(frm) notifier.notify(to, 'DustMail Invite', body) else: print() print(encode(packet.packet)) print() self.commandDone.set() def sendMessage(self): name=input("To: ") message=input("Message: ") PendingMessage(reader, name, message) def printHelp(self): print('num: read message num') print('x: quit') print('l: list messages') print('a: add invite') print('i: make invite') print('s: send message') self.commandDone.set()
try: keys.loadKeypair('config/id.yaml') except: print('Generating server keypair...') keys.createKeypair() keys.saveKeypair('config/id.yaml') keys.loadKnownHosts('config/knownhosts.yaml') keys.loadIncomingInvites('config/incoming_invites.ip') keys.loadOutgoingInvites('config/outgoing_invites.ip') router=PacketRouter(v6, inport, keys, passwd) router.connect(trackerAddr[0], trackerAddr[1]) tracker=TrackerClient(router) router.start() keypair=keys.getKeypair() pubkey=keypair.public invite=keys.generateInvite(inport, v6=v6) tracker.putInviteForPeer(encodeAddress((host, inport)), encode(invite.message)) endpoints=YamlMap('config/endpoints.yaml') for key in endpoints.values(): tracker.putPeerForEndpoint(key, [encode(pubkey.bytes), encodeAddress((host,inport))]) wait()
class DustmailReader: def __init__(self, router, endpoint): self.router = router self.endpoint = endpoint self.keys = router.keys self.maildir = 'spool/' + encode(endpoint.public.bytes) self.addressBook = YamlMap('config/dustmail-addressbook.yaml') self.done = Event() self.commandDone = Event() self.book = YamlMap('config/dustmail-addressbook.yaml') dustmailConfig = YamlMap('config/dustmail-config.yaml') try: destAddress = dustmailConfig['tracker'] except: entry = self.addInvite() destAddress = entry['tracker'] dustmailConfig['tracker'] = destAddress dest, outport, v6 = decodeAddress(destAddress) print('Registering with tracker...') self.tracker = TrackerClient(self.router, addr=(dest, outport)) host = getPublicIP(v6) inport = dustmailConfig['port'] self.tracker.putPeerForEndpoint(encode(self.endpoint.public.bytes), [ encode(self.endpoint.public.bytes), encodeAddress((host, inport)) ]) invite = self.keys.generateInvite(inport, v6=v6) self.tracker.putInviteForPeer(encodeAddress((host, inport)), encode(invite.message)) self.trackback = self.router.getService('trackback') def start(self): print('-' * 40) msgs = self.displayList() command = None while command != 'x': command = input('> ').strip() try: num = int(command) self.displayMessage(msgs[num - 1][1]) except: if command == 'l': msgs = self.displayList() else: self.parseCommand(command) def displayList(self): # msgs=os.listdir(maildir) msgs = [] for file in glob.glob(self.maildir + '/*.*'): stats = os.stat(file) lastmod_date = time.localtime(stats[8]) date_file_tuple = lastmod_date, file msgs.append(date_file_tuple) if len(msgs) == 0: print("No messages.") else: msgs.sort() msgs.reverse() for x in range(len(msgs)): date, fname = msgs[x] frm = fname.split('/')[-1].split('-')[0] modtime = time.strftime("%m/%d/%Y %I:%M%p", date) frmName = self.nameForPubkey(frm) if not frmName: frmName = frm print(str(x + 1) + ': ' + frmName + ' ' + modtime) return msgs def nameForPubkey(self, pubkey): for name in self.book.keys(): key = self.book[name]['pubkey'] if key == pubkey: return name return None def displayMessage(self, fname): f = open(fname, 'r') msg = f.read() f.close() data = decode(msg) onion = OnionPacket() #print(onion) try: onion.decodeOnionPacket(self.endpoint, data) except: traceback.print_exc() #print(onion) print(onion.data.decode('ascii')) def parseCommand(self, command): self.commandDone.clear() if command == 'x': self.commandDone.set() self.done.set() sys.exit(0) elif command == 'a': self.addInvite() elif command == 'i': self.makeInvite() elif command == 's': self.sendMessage() elif command == '?': self.printHelp() waitForEvent(self.commandDone) def addInvite(self): pf = input("Load invite from Paste or File [P/f]? ") if pf == 'f': filename = input("Load invite from filename: ").strip() f = open(filename, 'rb') data = f.read() f.close() else: data = decode(input("Past invite: ")) passwd = input("Decrypt invite with password: "******"Name for this endpoint: ") try: entry = self.book[name] except: entry = {} entry['pubkey'] = encode(packet.pubkey) entry['tracker'] = encodeAddress((invite.ip, invite.port)) self.book[name] = entry self.commandDone.set() return entry def makeInvite(self): self.trackback.setPutTrackerInviteCallback(self.gotInvite) self.tracker.getTrackerInvite() def gotInvite(self, invite): time.sleep(1) print() ps = input("Print, Save, or Email [P/s/e]? ") passwd = input("Encrypt invite with password: "******"Save invite to filename: ").strip() if filename != '': f = open(filename, 'wb') f.write(packet.packet) f.close() elif ps == 'e': frm = input("Your email: ") to = input("Recipient email: ") name = input("Your name on DustMail: ") body = """ You have been invited to communicate with %s via DustMail. Use the following invite code: %s """ % (name, encode(packet.packet)) emailConfig = YamlMap('config/emailServer.yaml') try: smtpHost = emailConfig['smtpHost'] except: smtpHost = input("SMTP Host: ") emailConfig['smtpHost'] = smtpHost notifier = Notifier(frm) notifier.notify(to, 'DustMail Invite', body) else: print() print(encode(packet.packet)) print() self.commandDone.set() def sendMessage(self): name = input("To: ") message = input("Message: ") PendingMessage(reader, name, message) def printHelp(self): print('num: read message num') print('x: quit') print('l: list messages') print('a: add invite') print('i: make invite') print('s: send message') self.commandDone.set()