import paramiko, os, sys, subprocess, get_runtime, wx # , keyring from typing import NoReturn from ui import Frame from threading import Thread def main(): host = frame.host.GetValue() localhost = frame.localhost.GetValue() netid = frame.net_id.GetValue() sshPass = frame.password.GetValue() password = frame.vnc_passwd.GetValue() kill_when_exit = frame.kill_when_exit.GetValue() if not host or not localhost or not netid or not sshPass or not password: wx.MessageBox("At least one of the box are left empty. Please make sure you fill out ALL boxes!!", "Empty Input", wx.ICON_ERROR) return frame.run.Enable(False) ssh = paramiko.SSHClient() sys.stdout.write(f'connecting to {host}\n') frame.status.SetLabelText(f'connecting to host') port = get_server(ssh, host, netid, sshPass, password) if int(port) == -1: wx.MessageBox("Your netID and password for that netID does not match the one in the ECE system!", "Wrong " "Credentials", wx.ICON_ERROR) frame.run.Enable(True) frame.status.SetLabelText(u"Click 'RUN' to begin, hover over any boxes to show hints") return display = port if int(port) < 10: port = "0" + port port = "59" + port java = os.path.join(get_runtime.RUNTIME_PATH, get_runtime.get_java_path()) frame.status.SetLabelText(f'initializing java') vnc_cmd = f'{java} -jar VNC_UWEE.jar -host="{localhost}" -port="{port}" -sshHost="{host}" -sshUser="{netid}" -sshPassword="{sshPass}" -password="{password}"' frame.status.SetLabelText(f'VNC session started!') out = subprocess.Popen(vnc_cmd, shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = out.communicate() open("launcher.log", "w").write(stderr.decode('utf-8')) if out.returncode: sys.stderr.write(f"{stderr.decode('utf-8')}\nProgram crashed with code {out.returncode}") if kill_when_exit: kill_srv(ssh, host, netid, sshPass, display) frame.run.Enable(True) frame.status.SetLabelText(u"Click 'RUN' to begin, hover over any boxes to show hints") def get_server(client: paramiko.SSHClient, host: str, username: str, password: str, vnc_passwd: str) -> str: client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) try: client.connect(host, username=username, password=password) except paramiko.ssh_exception.AuthenticationException: return '-1' sys.stdout.write("connected, sending command\n") ssh_stdin, ssh_stdout, ssh_stderr = client.exec_command("vncserver && vncserver -list") ssh_stdin.channel.shutdown_write() if "You will require a password to access your desktops" in ssh_stderr.read().decode('utf-8'): # create the vncserver's password if not done so, then create the session again and just return, since ssh_stdout did not refreshes outside the if # TODO: add option that user can have a view-only password ssh_stdin, ssh_stdout, ssh_stderr = client.exec_command("vncpasswd") ssh_stdin.write(f"{vnc_passwd}\n") ssh_stdin.write(f"{vnc_passwd}\n") ssh_stdin.write("n\n") ssh_stdin.flush() ssh_stdin, ssh_stdout, ssh_stderr = client.exec_command("vncserver && vncserver -list") return ssh_stdout.readlines()[-1].split()[0][1:] return ssh_stdout.readlines()[-1].split()[0][1:] def kill_srv(client: paramiko.SSHClient, host: str, username: str, password: str, port: str) -> NoReturn: client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) client.connect(host, username=username, password=password) client.exec_command(f"vncserver -kill :{port}") def on_chk(e): if frame.localhost_ck.GetValue(): frame.localhost.Enable(False) frame.localhost.SetValue("127.0.0.1") else: frame.localhost.Enable(True) def run(e): # wrapper for main to ensure is not frozen I guess task = Thread(target=main) task.setDaemon(True) task.start() if __name__ == '__main__': console_title = 'Program Crashed! Here are the details' # this is there for now to redirect any errors app = wx.App(useBestVisual=True) frame = Frame(None) app.SetTopWindow(frame) # set where the uncaught errors should be displayed console = wx.PyOnDemandOutputWindow(console_title) console.SetParent(frame) # sys.stderr = console frame.SetTitle("ECE-SSH_dev_1.1") frame.run.Bind(wx.EVT_BUTTON, run) frame.Bind(wx.EVT_CHECKBOX, on_chk) frame.Show() app.MainLoop() # MAGIC_USERNAME_KEY = 'im_the_magic_username_key' # # # the service is just a namespace for your app # service_id = 'IM_YOUR_APP!' # # username = 'dustin' # # # save password # keyring.set_password(service_id, username, "password") # # # optionally, abuse `set_password` to save username onto keyring # # we're just using some known magic string in the username field # keyring.set_password(service_id, MAGIC_USERNAME_KEY, username) # # username = keyring.get_password(service_id, MAGIC_USERNAME_KEY) # # password = keyring.get_password(service_id, username) # # print(username, password)