Passwords saved, networking fixes.

This commit is contained in:
Scott Duensing 2023-09-21 19:49:34 -05:00
parent 738a9035ef
commit 78ee5662fc
7 changed files with 185 additions and 67 deletions

View file

@ -53,6 +53,7 @@ unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
max_length = 32
select_all_on_focus = true
[node name="Label2" type="Label" parent="SettingsWindow/MarginContainer/VBoxContainer/NamesGridContainer"]
layout_mode = 2
@ -63,6 +64,7 @@ horizontal_alignment = 2
unique_name_in_owner = true
layout_mode = 2
max_length = 32
select_all_on_focus = true
[node name="Label3" type="Label" parent="SettingsWindow/MarginContainer/VBoxContainer/NamesGridContainer"]
layout_mode = 2
@ -73,6 +75,7 @@ horizontal_alignment = 2
unique_name_in_owner = true
layout_mode = 2
max_length = 32
select_all_on_focus = true
[node name="MarginContainer" type="MarginContainer" parent="SettingsWindow/MarginContainer/VBoxContainer"]
custom_minimum_size = Vector2(0, 20)
@ -94,6 +97,7 @@ horizontal_alignment = 2
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
select_all_on_focus = true
[node name="Label2" type="Label" parent="SettingsWindow/MarginContainer/VBoxContainer/ServerGridContainer"]
layout_mode = 2
@ -106,6 +110,7 @@ layout_mode = 2
max_value = 65535.0
page = 100.0
rounded = true
select_all_on_focus = true
[node name="MarginContainer2" type="MarginContainer" parent="SettingsWindow/MarginContainer/VBoxContainer"]
custom_minimum_size = Vector2(0, 20)
@ -126,6 +131,7 @@ horizontal_alignment = 2
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
select_all_on_focus = true
[node name="IPCheckButton" type="CheckButton" parent="SettingsWindow/MarginContainer/VBoxContainer/AddressesGridContainer"]
unique_name_in_owner = true
@ -141,6 +147,7 @@ horizontal_alignment = 2
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
select_all_on_focus = true
[node name="MACCheckButton" type="CheckButton" parent="SettingsWindow/MarginContainer/VBoxContainer/AddressesGridContainer"]
unique_name_in_owner = true

View file

@ -5,7 +5,6 @@ signal _dialog_closed
var _dialog
var _line_edit
var _result
@ -64,27 +63,37 @@ func confirm(title: String, text: String, parent: Node = null):
return _result
func prompt(title: String, text: String, parent: Node = null, chars: int = 32):
func password(title: String, text: String, dialogName: String = "", parent: Node = null, chars: int = 32):
# Do we have a password for this dialog?
if dialogName == "":
dialogName = title.to_lower().replace(" ", "_")
if Settings.passwords.has(dialogName):
return Settings.passwords[dialogName]
# No password, show dialog.
var hbox := HBoxContainer.new()
hbox.size_flags_horizontal = Control.SIZE_EXPAND_FILL
var label := Label.new()
label.text = text
hbox.add_child(label)
hbox.add_spacer(false)
_line_edit = LineEdit.new()
var size = _line_edit.get_minimum_size()
size.x = _line_edit.get_theme_default_font_size() * chars
_line_edit.set_custom_minimum_size(size)
_line_edit.max_length = chars
_line_edit.expand_to_text_length = true
_line_edit.secret = true
_line_edit.select_all_on_focus = true
_line_edit.text_submitted.connect(_submitted)
hbox.add_child(_line_edit)
var line_edit = LineEdit.new()
var size = line_edit.get_minimum_size()
size.x = line_edit.get_theme_default_font_size() * chars
line_edit.set_custom_minimum_size(size)
line_edit.max_length = chars
line_edit.expand_to_text_length = true
line_edit.secret = true
line_edit.select_all_on_focus = true
line_edit.text_submitted.connect(_submitted)
hbox.add_child(line_edit)
hbox.add_spacer(false)
var check_button = CheckButton.new()
check_button.text = "Save"
hbox.add_child(check_button)
_dialog = AcceptDialog.new()
_dialog.title = title
_dialog.unresizable = true
_dialog.register_text_enter(_line_edit)
_dialog.register_text_enter(line_edit)
var cancel = _dialog.add_cancel_button("Cancel")
_dialog.get_ok_button().pressed.connect(_accepted)
cancel.pressed.connect(_canceled)
@ -97,6 +106,48 @@ func prompt(title: String, text: String, parent: Node = null, chars: int = 32):
_dialog.popup_centered()
await _dialog_closed
if _result:
return _line_edit.text
if check_button.button_pressed:
# Save password
Settings.passwords[dialogName] = line_edit.text
Settings.save_settings()
return line_edit.text
else:
return null
func prompt(title: String, text: String, parent: Node = null, chars: int = 32):
var hbox := HBoxContainer.new()
hbox.size_flags_horizontal = Control.SIZE_EXPAND_FILL
var label := Label.new()
label.text = text
hbox.add_child(label)
hbox.add_spacer(false)
var line_edit = LineEdit.new()
var size = line_edit.get_minimum_size()
size.x = line_edit.get_theme_default_font_size() * chars
line_edit.set_custom_minimum_size(size)
line_edit.max_length = chars
line_edit.expand_to_text_length = true
line_edit.secret = false
line_edit.select_all_on_focus = true
line_edit.text_submitted.connect(_submitted)
hbox.add_child(line_edit)
_dialog = AcceptDialog.new()
_dialog.title = title
_dialog.unresizable = true
_dialog.register_text_enter(line_edit)
var cancel = _dialog.add_cancel_button("Cancel")
_dialog.get_ok_button().pressed.connect(_accepted)
cancel.pressed.connect(_canceled)
_dialog.add_child(hbox)
if parent == null:
var scene_tree = Engine.get_main_loop()
scene_tree.current_scene.add_child(_dialog)
else:
parent.add_child(_dialog)
_dialog.popup_centered()
await _dialog_closed
if _result:
return line_edit.text
else:
return null

View file

@ -1,5 +1,5 @@
# Things to do:
# - Add libzstd
# - Embed the "edge" binary and extract it if needed.
#
# Issues to watch:
# - https://github.com/ntop/n2n/issues/1090 (P2P connections still occupy server traffic)
@ -51,18 +51,36 @@ func _data_recieved(type, data):
Peers.start_server(_ip, PEER_BASE_PORT + 1, Settings.user_name_line_edit.text, Settings.uuid)
if type == "edges":
if Peers.update(data):
_draw_tree()
# Handle empty peer list.
if data.size() == 0 and peers_tree.get_root() != null:
peers_tree.clear()
func _draw_tree():
# Redraw peer tree.
peers_tree.clear()
#***TODO**** We should really be displaying things in columns.
var root = peers_tree.create_item()
for peer in Peers.peerArray:
print(peer["online"])
if peer["online"]:
if peer["online"] or true:
var debug = str(peer["online"]) + " "
if peer["tcp"] == null:
debug = debug + "NULL"
else:
match peer["tcp"].get_status():
StreamPeerTCP.STATUS_NONE:
debug = debug + "None"
StreamPeerTCP.STATUS_CONNECTING:
debug = debug + "Connecting"
StreamPeerTCP.STATUS_CONNECTED:
debug = debug + "Connected " + peer["tcp"].get_connected_host()
StreamPeerTCP.STATUS_ERROR:
debug = debug + "Error"
_:
debug = debug + "Unknown"
var child = peers_tree.create_item(root)
child.set_text(0, peer["user"] + " (" + peer["ip"] + ")")
# Handle empty peer list.
if data.size() == 0 and peers_tree.get_root() != null:
peers_tree.clear()
child.set_text(0, peer["user"] + " (" + peer["ip"] + ") " + debug)
func _go_offline():

View file

@ -11,14 +11,16 @@ func _ready():
func _received_packet(peer, verb, payload):
match verb:
"online":
if peer["online"] != payload["status"]:
peer["online"] = payload["status"]
"status":
for key in payload:
if peer[key] != payload[key]:
peer[key] = payload[key]
peer["refresh"] = true
if !peer["online"]:
Peers.disconnect_peer(peer)
_:
print("UNKNOWN PACKET")
print("UNKNOWN VERB: ", verb)
print(peer)
print(verb)
print(payload)
print()

View file

@ -49,7 +49,7 @@ func _on_timer_timeout():
if peer["tcp"] != null:
peer["tcp"].poll()
if peer["tcp"].get_status() == StreamPeerTCP.STATUS_CONNECTED:
send_to_peer(peer, "online", { "status": true })
send_to_peer(peer, "status", { "online": true, "user": _userInfo["user"], "uuid": _userInfo["uuid"] })
func _process(_delta):
@ -92,7 +92,9 @@ func _tcp_server():
peer["tcp"].disconnect_from_host()
peer["tcp"] = new_peer
print("Updated peer ", peer["ip"], ":", peer["port"])
peer["tcp"].set_no_delay(true)
peer["tcp"].poll()
if peer["tcp"].get_status() == StreamPeerTCP.STATUS_CONNECTED:
peer["tcp"].set_no_delay(true) # ***TODO*** This throws an error some times.
# Process incoming data and attempt connections.
for peer in peerArray:
@ -125,6 +127,14 @@ func clear():
peerArray.clear()
func disconnect_peer(peer):
if peer["tcp"] != null:
send_to_peer(peer, "status", { "online": false })
peer["tcp"].disconnect_from_host()
peer["tcp"] = null
print("Disconnected peer ", peer["ip"], ":", peer["port"])
func is_running():
return _serverRunning
@ -158,11 +168,7 @@ func stop_server():
# Tear down network.
_serverRunning = false
for peer in peerArray:
if peer["tcp"] != null:
send_to_peer(peer, "online", { "status": false })
peer["tcp"].disconnect_from_host()
peer["tcp"] = null
print("Disconnected peer ", peer["ip"], ":", peer["port"])
disconnect_peer(peer)
_tcp.stop()
@ -194,6 +200,10 @@ func update(peersFromCPP: Array):
for oldPeer in oldArray:
if oldPeer["ip"] == peerCPP["ip"]:
found = true
# Sometimes we get duplicates, prevent adding a peer twice.
for knownPeer in peerArray:
if knownPeer["ip"] == oldPeer["ip"]:
continue
peerCPP = oldPeer
if !found:
# We didn't have them. Add needed records.
@ -219,6 +229,6 @@ func update(peersFromCPP: Array):
# Sort new array.
peerArray.sort_custom(_sort_by_ip)
print("Peers After: ", peerArray)
#print("Peers After: ", peerArray)
return changed

View file

@ -9,7 +9,7 @@ var _root_password = null
func _elevate_unix(program: String, arguments: PackedStringArray):
_root_password = await Dialog.prompt("Root Access Needed", "Password:")
_root_password = await Dialog.password("Root Access Needed", "Password:")
if _root_password == null:
return -1
_ask_pass_password = Util.generate_password()
@ -26,7 +26,7 @@ func _elevate_unix(program: String, arguments: PackedStringArray):
return pid
func _elevate_windows(program: String, arguments: PackedStringArray):
func _elevate_windows(_program: String, _arguments: PackedStringArray):
pass

View file

@ -16,11 +16,16 @@ extends Control
@onready var save_settings_button = %SaveSettingsButton
var _crypto
var _key
var uuid: String = ""
var passwords := {}
func load_settings():
# Do we have a configuration yet?
passwords = {}
var config = ConfigFile.new()
var err = config.load("user://network.cfg")
if err != OK:
@ -43,7 +48,6 @@ func load_settings():
# Load settings.
user_name_line_edit.text = config.get_value("settings", "userName", "Change Me!")
network_name_line_edit.text = config.get_value("settings", "networkName", "Change Me!")
network_password_line_edit.text = config.get_value("settings", "networkPassword", "Change Me!")
server_line_edit.text = config.get_value("settings", "server", "supernode.kangaroopunch.com")
server_port_spin_box.value = config.get_value("settings", "serverPort", 7777)
ip_line_edit.text = config.get_value("settings", "ipAddress", "10.0.0.10")
@ -55,6 +59,13 @@ func load_settings():
compression_check_button.button_pressed = config.get_value("settings", "compression", true)
auto_start_check_button.button_pressed = config.get_value("settings", "autoStart", false)
uuid = config.get_value("settings", "identity", Uuid.v4())
# Load passwords.
passwords["networkPassword"] = ""
if config.has_section("passwords"):
for key in config.get_section_keys("passwords"):
passwords[key] = config.get_value("passwords", key).hex_decode()
passwords[key] = _crypto.decrypt(_key, passwords[key]).get_string_from_utf8()
network_password_line_edit.text = passwords["networkPassword"]
func save_settings():
@ -76,9 +87,9 @@ func save_settings():
# Save it.
var config = ConfigFile.new()
# Settings.
config.set_value("settings", "userName", user_name_line_edit.text)
config.set_value("settings", "networkName", network_name_line_edit.text)
config.set_value("settings", "networkPassword", network_password_line_edit.text)
config.set_value("settings", "server", server_line_edit.text)
config.set_value("settings", "serverPort", server_port_spin_box.value)
config.set_value("settings", "ipAddress", ip_line_edit.text)
@ -89,9 +100,27 @@ func save_settings():
config.set_value("settings", "autoStart", auto_start_check_button.button_pressed)
#config.set_value("settings", "position", DisplayServer.window_get_position())
config.set_value("settings", "identity", uuid)
# Passwords.
passwords["networkPassword"] = network_password_line_edit.text
for password in passwords:
var encrypted = _crypto.encrypt(_key, passwords[password].to_utf8_buffer())
config.set_value("passwords", password, encrypted.hex_encode())
config.save("user://network.cfg")
func _init_crypto():
_crypto = Crypto.new()
_key = CryptoKey.new()
if !FileAccess.file_exists("user://rsa.key") or !FileAccess.file_exists("user://rsa.crt"):
var cert = X509Certificate.new()
_key = _crypto.generate_rsa(4096)
cert = _crypto.generate_self_signed_certificate(_key, "CN=kangaroopunch.com,O=Kangaroo Punch Studios,C=US")
_key.save("user://rsa.key")
cert.save("user://rsa.crt")
else:
_key.load("user://rsa.key")
func _on_ip_check_button_toggled(_toggled_on):
ip_line_edit.editable = !ip_check_button.button_pressed
@ -110,5 +139,6 @@ func _on_settings_window_close_requested():
func _ready():
_init_crypto()
load_settings()