""" Jake Zaia 2018-10-12 Manages SSH config files, and supports a more user-friendly terminal based way of creating them """ import os #This is the location of where the SSH SSH_CONFIG_FILE_LOC = os.path.expanduser('~/.ssh/config') bar = '================================\n' def config_exists(): """ Checks if an SSH config file exists at the desired path """ return os.path.isfile(SSH_CONFIG_FILE_LOC) def get_config(): """ Returns the contents of the SSH config file as a string """ if not config_exists(): return '' f = open(SSH_CONFIG_FILE_LOC, 'r') ret = f.read() f.close() return ret def get_entries(): """ Creates a list of dictionaries where each dictionary contains all the information about a Host in the SSH config. """ ret = [] config = get_config().split('\n') #Operate on each line in the config for i in range(len(config)): #Add a new host entry if config[i][0:4] == 'Host': ret.append({}) ret[-1]['Host'] = config[i][5:] #Add information to the current host if "\t" in config[i]: config[i] = config[i].strip() key = config[i][0: config[i].find(' ')] value = config[i][1 + config[i].find(' '):] ret[-1][key] = value return ret def print_entry_info(entry): """ Conveniently displays the information for one entry in the SSH Config Takes a dictionary as input. """ print("Host: {0}".format(entry['Host'])) print("HostName: {0}".format(entry['HostName'])) print("User: {0}".format(entry['User'])) #Optional if 'Port' in entry: print("Port: {0}".format(entry['Port'])) if 'IdentityFile' in entry: print("IdentityFile: {0}".format(entry['IdentityFile'])) def modify_entry(): """ Gets all current entries and allows the user to modify the current values. """ entries = get_entries() print("Which entry would you like to modify?") for i in range(len(entries)): print("{0}: {1}".format(i, entries[i]['Host'])) i = int(input()) #Print to ensure the correct property is specified print_entry_info(entries[i]); prop = input("Which property would you like to edit? (case sensitive) ") value = input("What should the new value be? ") entries[i][prop] = value #Update actual file push_config(entries) print("Successfully updated the entry.") def remove_entry(): """ Facilitates removing a singular entry from the SSH Config file """ entries = get_entries() print("Which entry would you like to remove?") for i in range(len(entries)): print("{0}: {1}".format(i, entries[i]['Host'])) i = int(input()) print(bar) #For safety print_entry_info(entries[i]); resp = input("Really delete this entry? [y/N] ") if (resp=='y' or resp=='Y' or resp.lower() == 'yes'): entries.pop(i) print("Successfully deleted.") push_config(entries) def push_config(config): """ Overwrites current config with an input list of dictionaries. Used as a helper to modify values in the SSH Config. """ f = open(SSH_CONFIG_FILE_LOC, 'w') for each in config: f.write("Host {0}\n".format(each['Host'])) f.write("\tHostName {0}\n".format(each['HostName'])) f.write("\tUser {0}\n".format(each['User'])) if 'Port' in each: f.write("\tPort {0}\n".format(each['Port'])) if 'IdentityFile' in each: f.write("\tIdentityFile {0}\n".format(each['IdentityFile'])) f.close() def create_entry(): """ Creates an SSH config file with information taken from a user """ print("Please input the relevent information for generating your config file.") host = input("Nickname for Host: ") hostname = input("Hostname: ") user = input("Username: ") #Port is optional port = input("Would you like to specify a port?(y/N)") if (port == 'y' or port == 'Y' or port.lower() =='yes'): port = input("Port number: ") else: port = None #SSH public key location is optional identityfile = input("Would you like to specify an ssh public key location?(y/N)") if (identityfile == 'y' or identityfile == 'Y' or identityfile.lower() =='yes'): identityfile = input("SSH Public key file location: ") #Write info to config file if config_exists(): f = open(SSH_CONFIG_FILE_LOC, 'a') else: f = open(SSH_CONFIG_FILE_LOC, 'w') f.write("Host {0}\n".format(host)) f.write("\tHostName {0}\n".format(hostname)) f.write("\tUser {0}\n".format(user)) if port: f.write("\tPort {0}\n".format(port)) if identityfile: f.write("\tIdentityFile {0}\n".format(identityfile)) f.close() print("Successfully created the entry.") if __name__ == '__main__': cont = True while(cont): print("Modify your SSH Config file. Please Select an option:") print("0: Add a new entry") print("1: List all information") print("2: Modify an existing entry") print("3: Remove an entry") print("Any other number: exit") resp = input() print(bar) if resp == '0': create_entry() elif resp == '1': for each in get_entries(): print() print_entry_info(each) elif resp == '2': modify_entry() elif resp == '3': remove_entry() else: cont = False print(bar)