#!/usr/bin/env python2 # Copyright (c) 2012 Sakari Bergen # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . __author__ = 'Sakari Bergen' import pygtk pygtk.require('2.0') import gtk import subprocess import os import getpass class AbortButton: def abort_or_allow(self, widget, data=None): if self.allowed: self.session.abort() self.allowed = False self.button.set_label(self.allow_text) else: self.session.allow() self.allowed = True self.button.set_label(self.abort_text) def delete_event(self, widget, event, data=None): return False def destroy(self, widget, data=None): self.session.close_screen() gtk.main_quit() def __init__(self, session): self.session = session self.window = gtk.Window(gtk.WINDOW_TOPLEVEL) self.window.connect("delete_event", self.delete_event) self.window.connect("destroy", self.destroy) self.window.set_border_width(20) self.window.set_keep_above(True) self.allow_text = "Allow remote access" self.abort_text = "Abort session!" self.allowed = False self.button = gtk.Button(self.allow_text) self.button.connect("clicked", self.abort_or_allow, None) self.window.add(self.button) self.button.show() self.window.show() def main(self): gtk.main() class ScreenSession: def __init__(self): self.script_name = 'attach-remote-debug.sh' self.screen_name = self.prompt_with_default("Enter name for screen session", "remote-debug") self.attach_command = 'screen -xS ' + self.screen_name self.create_attach_script() def launch_screen(self): print("Launching screen...") subprocess.call(["screen", "-dmS", self.screen_name]) self.send_command(["multiuser", "on"]) def close_screen(self): print("Closing the screen...") self.send_command("quit") def create_attach_script(self): print("") print("You will need to create a guest account for the remote user, and provide its credentials to the person in the other end.") self.username = raw_input("Enter remote username: ") self.remote_attach_command = 'screen -xS ' + getpass.getuser() + '/' + self.screen_name filename = '/home/' + self.username + '/' + self.script_name cmd = "sudo sh -c 'echo \"{0}\" > {1} && chmod u+x {1} && chown {2} {1}'".format(self.remote_attach_command, filename, self.username) print("") print("The remote user will need to execute the command '{0}' in order to attach".format(self.remote_attach_command)) print("This can be made easier by adding this command to a script located at {0}".format(filename)) print("") print("The following command will be used to create the script:") print(cmd) print("") if self.prompt_yn("Do you want to run the above command (please check for bad input)?", True): subprocess.call([cmd], shell=True) def attach(self): subprocess.call([self.attach_command], shell=True) def abort(self): #print "Aborting!" self.send_command(["aclchg", self.username, "-rw", '#?']) def allow(self): #print "Allowing access to remote user!" self.send_command(["aclchg", self.username, "+rw", '#?']) def send_command(self, commands): args = ["screen", "-S", self.screen_name, "-X"] if isinstance(commands, str): args.append(commands) else: for command in commands: args.append(command) subprocess.call(args) def prompt_with_default(self, prompt, default): val = raw_input((prompt + " (default: {0}) ").format(default)) if val != "": return val else: return default def prompt_yn(self, prompt, default): yn = "invalid" while yn != "y" and yn != "n" and yn != "": yn = raw_input(prompt + " (Y/n) " if default else " (y/N) ") if yn == "y": return True if yn == "": return default else: return False if __name__ == "__main__": session = ScreenSession() print("") print("The screen session will now automatically attach " "and you are ready to invite the remote user to log in and attach to the screen " "either by running the commands manually, or by invoking the script (if you created it)") print("") print("A window with controls for allowing and disallowing remote access to this screen will appear, " "closing this window will close the whole session, while allow/abort will only " "modify the access rules to your screen session") raw_input("Press enter to continue!") if os.fork() == 0: button = AbortButton(session) button.main() else: session.launch_screen() session.attach()