Advertisement
Guest User

Untitled

a guest
Jul 20th, 2019
114
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 25.78 KB | None | 0 0
  1. # Use the ZRE protocol (v3) as a discovery layer to build a CJDNS mesh.
  2.  
  3. import traceback
  4. from time import sleep
  5. import cjdns
  6. import uuid as uuid
  7. import re
  8. from cjdns import key_utils
  9. import zmq
  10. import _thread
  11. import netifaces as ni
  12. from pyre import Pyre, zhelper
  13. import queue
  14. from queue import Queue
  15. import json
  16. import sys
  17. from os import urandom
  18. import salsa20
  19.  
  20. PASS_EXCHANGE_HEAD = b"pe:"
  21.  
  22. KEY_NEGOTIATION_HEAD = b"kn:"
  23.  
  24. ENCRYPTED_MESSAGE_HEAD = b"em:"
  25.  
  26. Permissive_Encoding = 'cp437'
  27. debugging = False
  28. ADDRESSES = 'addresses'
  29. ADDRESS_LIST = 'ADDRESS_LIST'
  30. PUBKEY = 'pub_key'
  31. DISCOVERY = b'DISCOVERY'
  32. WORLD = b'WORLD'
  33. SESSION_PERSONAL_SECRET = urandom(32)
  34. cjdns_config_files = ["C:\\Program Files (x86)\\cjdns\\cjdroute.conf", "/etc/cjdns/cjdroute.conf", "/etc/cjdroute.conf"]
  35. cjdns_config_object = {}
  36.  
  37.  
  38. def make_to_send(foreign_public_key, local_public_key):
  39. shared_data = make_shared_data(foreign_public_key, local_public_key)
  40. to_send_int = shared_data * int(SESSION_PERSONAL_SECRET.hex(), 16)
  41. to_send_hex = hex(to_send_int)
  42. send_hex_ = to_send_hex[-64:]
  43. return bytes(send_hex_, Permissive_Encoding)
  44.  
  45.  
  46. def make_shared_secret(received_hex):
  47. try:
  48. secret_int = int(received_hex, 16)*int(SESSION_PERSONAL_SECRET.hex(), 16)
  49. except ValueError:
  50. print("bad key negotiation!")
  51. return None
  52. hexnum = hex(secret_int)[2:]
  53. # currently, key negotiation must be broken, so only 31 bytes of the key are useful. manually appending null byte.
  54. try: # fromhex fails with an odd number of hex digits, catch this.
  55. return bytes.fromhex(hexnum)[-31:]+bytes(1)
  56. except ValueError:
  57. return bytes.fromhex("0"+hexnum)[-31:]+bytes(1)
  58.  
  59.  
  60. def make_shared_data(foreign_public_key, local_public_key):
  61. int_foreign = cjd_pubkey_asint(foreign_public_key)
  62. int_local = cjd_pubkey_asint(local_public_key)
  63. shared_data_int = int_foreign * int_local
  64. return shared_data_int
  65.  
  66.  
  67. def get_cjd_pubkey(nodestring):
  68. splitstring = nodestring.split(sep=b".")
  69. try:
  70. pkey = splitstring[-2]
  71. except:
  72. return None
  73. return pkey+b".k"
  74.  
  75.  
  76. def cjd_pubkey_asint(pkey):
  77. try:
  78. as_int = int(key_utils.base32.decode(pkey[:-2]).hex(), 16)
  79. return as_int
  80. except ValueError:
  81. return 0
  82.  
  83. # the message queue contains individual ZRE protocol messages in byte-array form, ready for processing.
  84. message_queue = Queue()
  85. # the discovery queue is meant to facilitate the exchange of IP data, and thereafter trigger password negotiation
  86. discovery_queue = Queue() # (cjdns address, pubkey, ip address list, ZRE node)
  87. # the chat queue is used for miscellaneous chat messages, and is the channel used for encrypted password negotiation
  88. chat_queue = Queue() # (cjdns address, pubkey, group name, msg(em: if encrypted?), return to)
  89. # the negotiation queue is used for encrypted password negotiation (first secret exchange, then password exchange)
  90. negotiation_queue = Queue() # (cjdns address, pubkey, group name, msg(kn:key data or pe:encrypted pass), return to)
  91. # raw messages are parsed into 'actions' which, if relevant, are sorted into above queues.
  92. action_queue = Queue()
  93. # action (list) content:
  94. # index - meaning
  95. # 0 - message type
  96. # 1 - from node
  97. # 2 - cjdns address
  98. # 3 - message content; group name if SHOUT
  99. # 4 - SHOUT message content
  100. # 5 - cjdns public key
  101.  
  102.  
  103. def queue_to_action_queue(inqueue, outqueue):
  104. temp_dict = {}
  105. current_pointer = 0
  106. while True:
  107. try:
  108. last_thing = inqueue.get(timeout=1)
  109. if to_string(last_thing) in action_processor_dict:
  110. current_pointer = 0
  111. if temp_dict:
  112. outqueue.put_nowait(temp_dict.copy())
  113. outqueue.task_done()
  114. temp_dict.clear()
  115. temp_dict[current_pointer] = last_thing
  116. current_pointer += 1
  117. except queue.Empty:
  118. current_pointer = 0
  119. if temp_dict:
  120. outqueue.put_nowait(temp_dict.copy())
  121. outqueue.task_done()
  122. temp_dict.clear()
  123. continue
  124.  
  125.  
  126. def to_string(self):
  127. try:
  128. string = self.decode(Permissive_Encoding)
  129. return string
  130. except:
  131. return self
  132.  
  133.  
  134. def parse_if_dict(self):
  135. try:
  136. byte_string = self
  137. if byte_string[0] is b"{":
  138. return json.load(byte_string)
  139. return byte_string
  140. except:
  141. return None
  142.  
  143.  
  144. def process_action_queue(actions):
  145. # index - pre:before processing, post: after processing (meaning)
  146. # 0 - message type
  147. # 1 - from node
  148. # 2 - pre:public key and cjdns protocol string, post: cjdns address
  149. # 3 - message content; group name if SHOUT
  150. # 4 - SHOUT message content
  151. # 5 - pre:non-existent, post:cjdns public key
  152. while True:
  153. try:
  154. action = actions.get()
  155. action[0] = action.get(0)
  156. action[1] = action.get(1).hex()
  157. action[2] = get_cjd_pubkey(action.get(2))
  158. if action[2] is not b"incompatible peer":
  159. action[5] = to_string(action[2]) # save the key for easier future use
  160. try:
  161. action[2] = key_utils.to_ipv6(to_string(action.get(2)))
  162. except TypeError:
  163. action[2] = None
  164. action[3] = parse_if_dict(action.get(3))
  165. action[4] = parse_if_dict(action.get(4))
  166. do_action(action)
  167. except AttributeError:
  168. print("malformed message! ignoring.")
  169.  
  170.  
  171. action_processor_dict = {
  172. b"EXIT": lambda doing: close_cjdns_connection(doing[1]),
  173. b"ENTER": lambda doing: queue_shout(doing),
  174. b"JOIN": lambda doing: queue_shout(doing),
  175. b"LEAVE": lambda doing: close_cjdns_connection(doing[1]),
  176. b"WHISPER": lambda doing: queue_chat(doing),
  177. b"SHOUT": lambda doing: queue_shout(doing),
  178. }
  179.  
  180.  
  181. def do_action(todo=None):
  182. if todo is None:
  183. todo = {}
  184. action_processor_dict[todo[0]](todo)
  185.  
  186.  
  187. def queue_shout(shout_action):
  188. if shout_action[0] == "JOIN" or shout_action[0] == "LEAVE":
  189. shout_action[4] = shout_action[0]
  190. if shout_action[0] == "ENTER":
  191. shout_action[3] = DISCOVERY
  192. if shout_action[3] == DISCOVERY: # (cjdns address, pubkey, ip address list)
  193. discovery_queue.put_nowait((shout_action[2], shout_action[5], shout_action[4], shout_action[1]))
  194. else: # (cjdns address, pubkey, group name, msg, return node)
  195. try:
  196. chat_header = shout_action[4][:3]
  197. except TypeError:
  198. chat_header = None
  199. if KEY_NEGOTIATION_HEAD != chat_header and PASS_EXCHANGE_HEAD != chat_header:
  200. chat_queue.put_nowait(
  201. (shout_action[2], shout_action[5], shout_action[3], shout_action[4], shout_action[1])
  202. )
  203. else:
  204. negotiation_queue.put_nowait(
  205. (shout_action[2], shout_action[5], shout_action[3], shout_action[4], shout_action[1])
  206. )
  207.  
  208.  
  209. def queue_chat(chat_action): # (cjdns address, pubkey, group name (N/A), msg, return node)
  210. try:
  211. chat_header = chat_action[3][:3]
  212. except TypeError:
  213. chat_header = None
  214. if KEY_NEGOTIATION_HEAD != chat_header and PASS_EXCHANGE_HEAD != chat_header:
  215. chat_queue.put_nowait((chat_action[2], chat_action[5], None, chat_action[3], chat_action[1]))
  216. else:
  217. negotiation_queue.put_nowait((chat_action[2], chat_action[5], None, chat_action[3], chat_action[1]))
  218.  
  219.  
  220. def process_chats(inqueue):
  221. while True:
  222. temp_in = inqueue.get()
  223. try:
  224. in_ = temp_in[3][:3]
  225. if in_ != ENCRYPTED_MESSAGE_HEAD:
  226. print(node_or_ip(temp_in[4])+": "+str(temp_in[3]).strip())
  227. else:
  228. data_in = bytes(temp_in[3][4:], Permissive_Encoding)
  229. print(node_or_ip(temp_in[4]) + ": " + str(decrypt_data_from_node(temp_in[4], data_in)).strip())
  230. except TypeError:
  231. print(node_or_ip(temp_in[4]) + ": null")
  232.  
  233.  
  234. def node_or_ip(node_i_d):
  235. return verified_node_ips.get(node_i_d, node_i_d)
  236.  
  237.  
  238. def process_discovery(inqueue):
  239. # (cjdns address, pubkey, ip address list, ZRE node)
  240. # After discovering a new peer, send them a message to initiate negotiation (based on the provided pubKey)
  241. # If associated pubkey already has a shared secret associated, do not initiate negotiation, and ignore discovery
  242. while True:
  243. datain = inqueue.get()
  244. print("discovery: "+str(datain))
  245. foreign_node_id = datain[3]
  246. if not is_active_session(foreign_node_id):
  247. # do the stuff
  248. foreign_public_key = datain[1]
  249. send_key_negotiation(foreign_node_id, foreign_public_key)
  250. else:
  251. # ignore
  252. continue
  253.  
  254.  
  255. def send_key_negotiation(foreign_node_id, foreign_public_key):
  256. shared_data = make_to_send(foreign_public_key, localdata[PUBKEY][-54:])
  257. to_send = KEY_NEGOTIATION_HEAD + shared_data
  258. node.whisper(uuid.UUID(foreign_node_id), to_send)
  259. key_negotiation_sent[foreign_node_id] = True
  260.  
  261.  
  262. def send_encrypted_password(chat_node):
  263. # encrypt password and send pe: message with the encrypted data.
  264. if not node_local_pass.get(chat_node):
  265. # make local cjdns password for this node
  266. peerstring = cjdns_config_object["interfaces"]["UDPInterface"][0]["bind"]
  267. portnum = peerstring.split(":")[-1]
  268. portstr = ":" + str(portnum)
  269. new_pass = urandom(16)+bytes(portstr, Permissive_Encoding) # append :port number to this.
  270. cjdadmin.AuthorizedPasswords_add(str(new_pass), chat_node)
  271. node_local_pass[chat_node] = new_pass
  272. try:
  273. to_send = encrypt(chat_node, node_local_pass[chat_node])
  274. node.whisper(
  275. uuid.UUID(chat_node),
  276. PASS_EXCHANGE_HEAD+to_send
  277. )
  278. except Exception as e0:
  279. print(e0)
  280. cjdadmin.AuthorizedPasswords_remove(chat_node)
  281. try:
  282. print("attempting new key negotiation.")
  283. foreign_pubkey = get_from_sessions(chat_node)[0][1]
  284. send_key_negotiation(chat_node, foreign_pubkey)
  285. print("sent key negotiation.")
  286. except TypeError:
  287. print("no session found for this node!")
  288. print(cjdadmin.AuthorizedPasswords_list())
  289.  
  290.  
  291. def node_endpoint(chat_node):
  292. return node.peer_address(uuid.UUID(chat_node))
  293.  
  294.  
  295. # how to IV without sharing information: ( encrypt with first n-bits of secret appended, nonce is a random
  296. # (relatively small) number on encryption, decrypt by cycling through nonces until plaintext.)
  297. def encrypt(chat_node, data_in):
  298. # return encrypted data using verified secret (if possible/exists) try unverified secret otherwise.
  299. nonce = bytes(6) + urandom(2) # "small" (16 bit) random nonce?
  300. try:
  301. secretbit = node_verified_secret[chat_node][:3]
  302. cipher_text = salsa20.Salsa20_xor(data_in + secretbit, nonce, node_verified_secret[chat_node])
  303. return cipher_text
  304. except KeyError:
  305. secretbit = node_untrusted_secret[chat_node][:3]
  306. cipher_text = salsa20.Salsa20_xor(data_in + secretbit, nonce, node_untrusted_secret[chat_node])
  307. return cipher_text
  308.  
  309.  
  310. def decrypt_data_from_node(chat_node, data_in):
  311. # return decrypted data using verified secret (if possible/exists) try unverified secret otherwise.
  312. print("attempting decryption.")
  313. iterate = [0]
  314. while True:
  315. for x in range(len(iterate)):
  316. if iterate[x] > 255:
  317. iterate[x] = 0
  318. try:
  319. iterate[x+1] += 1
  320. except IndexError:
  321. iterate.append(1)
  322. iterbytes = bytes(iterate)
  323. left = 8-len(iterbytes)
  324. if left < 6:
  325. print("nonce not found, aborting decryption.")
  326. return data_in.strip()
  327. nonce = bytes(left)+iterbytes
  328. try:
  329. try:
  330. clear_attempt = salsa20.Salsa20_xor(
  331. data_in,
  332. nonce,
  333. node_verified_secret[chat_node]
  334. )
  335. current_secret_bit = node_verified_secret[chat_node][:3]
  336. # print(str(clear_attempt[-3:])+" : "+str(current_secret_bit))
  337. if clear_attempt[-3:] == current_secret_bit:
  338. print("decryption success.")
  339. return clear_attempt[:-4]
  340. except KeyError:
  341. clear_attempt = salsa20.Salsa20_xor(
  342. data_in,
  343. nonce,
  344. node_untrusted_secret[chat_node]
  345. )
  346. current_secret_bit = node_untrusted_secret[chat_node][:3]
  347. # print(str(clear_attempt[-3:])+" : "+str(current_secret_bit))
  348. if clear_attempt[-3:] == current_secret_bit:
  349. print("decryption success.")
  350. return clear_attempt[:-4]
  351. finally:
  352. iterate[0] += 1
  353. except TypeError as e1:
  354. print(e1)
  355. return data_in
  356. except ValueError as e2:
  357. print(e2)
  358. return data_in
  359.  
  360.  
  361. def attempt_cjdns_connection(attempt_pass, chat_node):
  362. # try to create a cjdns connection, return it's IPv6, else none.
  363. peer_endpoint = node_endpoint(chat_node)
  364. try:
  365. foreign_pubkey = get_from_sessions(chat_node)[0][1]
  366. except TypeError:
  367. print("no session found for this node!")
  368. return None
  369. try:
  370. ip = b"".join(bytes(peer_endpoint, Permissive_Encoding).split(b":")[1:-1]).strip(b'/')
  371. ip_string = str(ip + b":" + attempt_pass.split(b":")[-1], Permissive_Encoding)
  372. print(ip_string)
  373. print(foreign_pubkey)
  374. result = cjdadmin.UDPInterface_beginConnection(
  375. foreign_pubkey,
  376. ip_string,
  377. 0,
  378. password=str(b"".join(attempt_pass.split(b":")[:-2]), Permissive_Encoding)
  379. )
  380. except Exception as e0:
  381. result = {"error": e0}
  382. traceback.print_exc()
  383. if result["error"] == "none":
  384. return key_utils.to_ipv6(foreign_pubkey)
  385. else:
  386. print(result["error"])
  387. return None
  388.  
  389.  
  390. def close_cjdns_connection(chat_node):
  391. # close cjdns connection to pubkey of this ZRE node.
  392. # if this node had a local pass, disable it.
  393. cjdadmin.AuthorizedPasswords_remove(chat_node)
  394. try:
  395. cjdadmin.InterfaceController_disconnectPeer(get_from_sessions(chat_node)[0][1])
  396. except TypeError:
  397. print("no open CJDNS connection to close!")
  398.  
  399.  
  400. key_negotiation_sent = {}
  401. node_verified_secret = {}
  402. node_verified_pass = {}
  403. node_untrusted_pass = {}
  404. node_untrusted_secret = {}
  405. node_local_pass = {}
  406.  
  407.  
  408. # (cjdns address, pubkey, group name, msg(kn:key data or pe:encrypted pass), return to)
  409. def verified_session_handler(session):
  410. # accept and attempt password changes, and (non-cjdns) ip changes
  411. # ignore other operations (key negotiation)
  412. # later, accept blocks and other secure information from verified sessions.
  413. chat_header = session[3][:3]
  414. chat_data = session[3][3:]
  415. chat_node = session[4]
  416. node_info = (chat_node, session)
  417. if chat_header == PASS_EXCHANGE_HEAD:
  418. node_untrusted_pass[chat_node] = decrypt_data_from_node(chat_node, chat_data)
  419. if node_untrusted_pass[chat_node]:
  420. temp_ip = attempt_cjdns_connection(node_untrusted_pass[chat_node], chat_node)
  421. if temp_ip == session[0]:
  422. verify_session(node_info)
  423. node_verified_pass[chat_node] = node_untrusted_pass[chat_node]
  424. else:
  425. close_cjdns_connection(chat_node)
  426. untrust_session(node_info)
  427. print("verified: "+str(session))
  428.  
  429.  
  430. def temporary_session_handler(session):
  431. # verify or untrust session depending on whether it has access to the CJDNS connection it claims to be.
  432. # later, ignore blocks and transactions from this node until it is verified.
  433. chat_header = session[3][:3]
  434. chat_data = session[3][3:]
  435. chat_node = session[4]
  436. node_info = (chat_node, session)
  437. if chat_header == KEY_NEGOTIATION_HEAD:
  438. if key_negotiation_sent.get(chat_node) is None:
  439. send_key_negotiation(chat_node, session[2])
  440. node_untrusted_secret[chat_node] = make_shared_secret(chat_data)
  441. send_encrypted_password(chat_node)
  442. if chat_header == PASS_EXCHANGE_HEAD:
  443. node_untrusted_pass[chat_node] = decrypt_data_from_node(chat_node, chat_data)
  444. if node_untrusted_pass[chat_node]:
  445. temp_ip = attempt_cjdns_connection(node_untrusted_pass[chat_node], chat_node)
  446. if temp_ip == session[0]:
  447. verify_session(node_info)
  448. node_verified_pass[chat_node] = node_untrusted_pass[chat_node]
  449. else:
  450. close_cjdns_connection(chat_node)
  451. untrust_session(node_info)
  452. print("temporary: "+str(session))
  453.  
  454.  
  455. def untrusted_session_handler(session):
  456. # only accept key negotiations and move session back into temporary, without sending a pass
  457. # ignore any attempts at pass exchange or changes in any other credentials
  458. chat_header = session[3][:3]
  459. chat_data = session[3][3:]
  460. chat_node = session[4]
  461. node_info = (chat_node, session)
  462. if chat_header == KEY_NEGOTIATION_HEAD:
  463. send_key_negotiation(chat_node, session[2]) # will send kn: for the case where node failed to receive first one
  464. node_untrusted_secret[chat_node] = make_shared_secret(chat_data)
  465. re_queue_session(node_info)
  466. print("untrusted: "+str(session))
  467.  
  468.  
  469. verified_node_ips = {} # ip-node pairs of verified_sessions
  470. verified_sessions = {"qname": "verified_sessions"}
  471. temporary_sessions = {"qname": "temporary_sessions"}
  472. untrusted_sessions = {"qname": "untrusted_sessions"}
  473. sessions_dict = {
  474. verified_sessions["qname"]: verified_session_handler,
  475. temporary_sessions["qname"]: temporary_session_handler,
  476. untrusted_sessions["qname"]: untrusted_session_handler
  477. }
  478.  
  479.  
  480. def process_negotiations(inqueue):
  481. # (cjdns address, pubkey, group name, msg(kn:key data or pe:encrypted pass), return to)
  482. # negotiation process continues until CJDNS connection is attempted.
  483. # persistence/state/session is maintained on a per-ZRE node basis.
  484. # states become verified once a CJDNS session is established successfully with given credentials, persist shared key
  485. # states become untrusted if a CJDNS session is unsuccessfully attempted with given credentials
  486. while True:
  487. data_in = inqueue.get()
  488. session_init = (data_in[4], data_in)
  489. create_session(session_init)
  490. session_and_type = get_from_sessions(session_init[0])
  491. # noinspection PyTypeChecker
  492. sessions_dict[session_and_type[1]["qname"]](session_and_type[0])
  493.  
  494.  
  495. def untrust_session(node_info):
  496. node_i_d = node_info[0]
  497. if node_i_d in untrusted_sessions:
  498. return False
  499. else:
  500. temporary_sessions.pop(node_i_d, None)
  501. verified_sessions.pop(node_i_d, None)
  502. untrusted_sessions[node_i_d] = node_info[1]
  503. verified_node_ips.pop(node_i_d, None)
  504. if node_verified_pass:
  505. node_untrusted_pass[node_i_d] = node_verified_pass.pop(node_i_d)
  506. if node_verified_secret:
  507. node_untrusted_secret[node_i_d] = node_verified_secret.pop(node_i_d)
  508. return True
  509.  
  510.  
  511. def re_queue_session(node_info):
  512. node_i_d = node_info[0]
  513. if node_i_d in temporary_sessions:
  514. return False
  515. else:
  516. untrusted_sessions.pop(node_i_d, None)
  517. verified_sessions.pop(node_i_d, None)
  518. temporary_sessions[node_i_d] = node_info[1]
  519. if node_verified_pass:
  520. node_untrusted_pass[node_i_d] = node_verified_pass.pop(node_i_d)
  521. if node_verified_secret:
  522. node_untrusted_secret[node_i_d] = node_verified_secret.pop(node_i_d)
  523. return True
  524.  
  525.  
  526. def verify_session(node_info):
  527. node_i_d = node_info[0]
  528. if node_i_d in verified_sessions:
  529. return False
  530. else:
  531. temporary_sessions.pop(node_i_d, None)
  532. untrusted_sessions.pop(node_i_d, None)
  533. verified_sessions[node_i_d] = node_info[1]
  534. verified_node_ips[node_i_d] = node_info[1][0]
  535. node_verified_pass[node_i_d] = node_untrusted_pass.pop(node_i_d)
  536. node_verified_secret[node_i_d] = node_untrusted_secret.pop(node_i_d)
  537. return True
  538.  
  539.  
  540. def create_session(node_info):
  541. node_i_d = node_info[0]
  542. if node_i_d in verified_sessions or node_i_d in temporary_sessions or node_i_d in untrusted_sessions:
  543. temporary_sessions[node_i_d] = node_info[1]
  544. return False
  545. else:
  546. temporary_sessions[node_i_d] = node_info[1]
  547. return True
  548.  
  549.  
  550. def get_from_sessions(node_i_d):
  551. # returns session tuple, and the dict it came from. None if session does not exist. do not call a put after this.
  552. was_temporary = temporary_sessions.get(node_i_d, None)
  553. was_untrusted = untrusted_sessions.get(node_i_d, None)
  554. was_verified = verified_sessions.get(node_i_d, None)
  555. if was_temporary:
  556. return was_temporary, temporary_sessions
  557. elif was_untrusted:
  558. return was_untrusted, untrusted_sessions
  559. elif was_verified:
  560. return was_verified, verified_sessions
  561. else:
  562. return None
  563.  
  564.  
  565. def is_active_session(node_i_d):
  566. if node_i_d in temporary_sessions:
  567. return True
  568. if node_i_d in untrusted_sessions:
  569. return True
  570. if node_i_d in verified_sessions:
  571. return True
  572. return False
  573.  
  574.  
  575. def process_all_message_queues():
  576. _thread.start_new_thread(queue_to_action_queue, (message_queue, action_queue))
  577. _thread.start_new_thread(process_action_queue, (action_queue,))
  578. _thread.start_new_thread(process_chats, (chat_queue,))
  579. _thread.start_new_thread(process_negotiations, (negotiation_queue,))
  580. _thread.start_new_thread(process_discovery, (discovery_queue,))
  581.  
  582.  
  583. def consumer(pyre_node):
  584. while True:
  585. try:
  586. sleep(2)
  587. current_message_buffer = pyre_node.recv()
  588. if current_message_buffer:
  589. for message in current_message_buffer:
  590. message_queue.put_nowait(message)
  591. except Exception:
  592. print(traceback.print_exc())
  593.  
  594.  
  595. def caster(pyre_node):
  596. while True:
  597. try:
  598. sleep(1)
  599. sent = False
  600. currline = sys.stdin.readline().strip()
  601. for peer in pyre_node.peers():
  602. if peer in node_verified_secret:
  603. enc_line = encrypt(peer, bytes(currline, Permissive_Encoding))
  604. pyre_node.whisper(peer, b'em:'+enc_line)
  605. elif peer in node_untrusted_secret:
  606. enc_line = encrypt(peer, bytes(currline, Permissive_Encoding))
  607. pyre_node.whisper(peer, b'em:'+enc_line)
  608. else:
  609. pyre_node.whispers(peer, line)
  610. sent = True
  611. if not sent:
  612. print("no peers to send to!")
  613. except:
  614. traceback.print_exc()
  615. continue
  616.  
  617.  
  618. def update_local_addresses():
  619. addresses = {}
  620. for interface in interfaces:
  621. addresses[interface] = []
  622. addr_raw = ni.ifaddresses(interface)
  623. addr_raw_values = addr_raw.values()
  624. for addr_data in addr_raw_values:
  625. addresses[interface].append(addr_data[0]["addr"])
  626. localdata[ADDRESSES] = []
  627. for key in addresses:
  628. for address in addresses[key]:
  629. localdata[ADDRESSES].append(address)
  630. localdata[ADDRESSES] = list(set(localdata[ADDRESSES]))
  631.  
  632.  
  633. def comment_remover(text):
  634. def replacer(match):
  635. s = match.group(0)
  636. if s.startswith('/'):
  637. return None
  638. else:
  639. return s
  640. pattern = re.compile(
  641. r'//.*?$|/\*.*?\*/|\'(?:\\.|[^\\\'])*\'|"(?:\\.|[^\\"])*"',
  642. re.DOTALL | re.MULTILINE
  643. )
  644. return re.sub(pattern, replacer, text)
  645.  
  646.  
  647. context = zmq.Context()
  648. unprocessed_zyre = Queue()
  649. localdata = {}
  650. try:
  651. while True:
  652. try:
  653. cjdns_config_file = cjdns_config_files.pop()
  654. except IndexError:
  655. print("CJDNS config file location:")
  656. cjdns_config_files.append(sys.stdin.readline().strip())
  657. cjdns_config_file = cjdns_config_files.pop()
  658. try:
  659. raw_readlines = open(cjdns_config_file).readlines()
  660. readlines = []
  661. for line in raw_readlines:
  662. outline = line.strip()
  663. outline = comment_remover(outline)
  664. if outline:
  665. readlines.append(outline+"\n")
  666. input_str = str.join("", readlines).strip()
  667. input_str = comment_remover(input_str)
  668. cjdns_config_object = json.JSONDecoder().raw_decode(input_str)[0]
  669. except Exception as e:
  670. print(e)
  671. if cjdns_config_object:
  672. break
  673. admin_data = cjdns_config_object["admin"]
  674. ipAddr = str.join("", admin_data["bind"].split(":")[:-1])
  675. port = int(admin_data["bind"].split(":")[-1])
  676. password = admin_data["password"]
  677. cjdadmin = cjdns.connect(ipAddr, port, password)
  678. cjdadmin.InterfaceController_resetPeering()
  679. localdata[PUBKEY] = cjdadmin.Core_nodeInfo()["myAddr"]
  680. except ConnectionError:
  681. print("CJDNS is not running, or misconfigured.")
  682. interfaces = ni.interfaces()
  683. update_local_addresses()
  684. node = Pyre(name=localdata[PUBKEY])
  685. node.set_header(PUBKEY, localdata[PUBKEY])
  686. node.set_header(ADDRESS_LIST, json.dumps(localdata.get(ADDRESSES), ensure_ascii=False))
  687. localdata_json = json.dumps(localdata, ensure_ascii=False)
  688. node.join(DISCOVERY.decode(Permissive_Encoding))
  689. node.join(WORLD.decode(Permissive_Encoding))
  690. input_thread = _thread.start_new_thread(consumer, (node,))
  691. output_thread = _thread.start_new_thread(caster, (node,))
  692. process_all_message_queues()
  693. node.start()
  694. if debugging:
  695. node2 = Pyre(localdata[PUBKEY])
  696. node2.set_header(ADDRESS_LIST, json.dumps(localdata.get(ADDRESSES), ensure_ascii=False))
  697. mockNodes = [node2]
  698. for tempNode in mockNodes:
  699. tempNode.start()
  700. tempNode.join(DISCOVERY)
  701. tempNode.join(WORLD)
  702. _thread.start_new_thread(consumer, (tempNode,))
  703.  
  704. while True:
  705. try:
  706. continue
  707. except KeyboardInterrupt:
  708. for node_other in node_verified_pass:
  709. close_cjdns_connection(node_other)
  710. node.actor.close()
  711. raise
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement