-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgithub-sshkeys.py
More file actions
112 lines (89 loc) · 3.8 KB
/
github-sshkeys.py
File metadata and controls
112 lines (89 loc) · 3.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
from gitcred import Git
from logger import Logger
from pathlib import Path
import argparse
import json
import requests
from pycheck import is_supported_python
import sys
GITHUB_API = 'https://api.github.com'
SSH_FOLDER = Path.home() / ".ssh"
SSH_AUTHORIZED_KEYS_FILE = SSH_FOLDER / "authorized_keys"
###
### Fetches a user's public keys from GitHub
###
def fetch_public_keys(logger, username):
url = GITHUB_API + "/users/" + username + "/keys"
logger.log("Fetching public keys from GitHub...")
req = requests.get(url)
if req.status_code == 404:
### Unsupported in Python versions prior to Python 3.6
# logger.log(f"Username {username} could not be found.")
logger.log("Username %s could not be found" % username)
return None
return req.json()
###
### Ensures that .ssh folder and .authorized_keys file exists and both have
### the correct permissions
###
def ensure_authorized_keys_file(logger):
if not SSH_FOLDER.is_dir():
logger.log("\"~/.ssh\" folder does not exist yet. Creating folder with permission 700.")
SSH_FOLDER.mkdir(mode=0o700)
if not SSH_AUTHORIZED_KEYS_FILE.is_file():
logger.log("\"~/.ssh/authorized_keys\" does not exist yet. Creating file with permission 600.")
SSH_AUTHORIZED_KEYS_FILE.touch(mode=0o600)
###
### Reads ~/.ssh/authorized_keys and returns a list
###
def get_authorized_keys(logger):
ensure_authorized_keys_file(logger)
with open(str(SSH_AUTHORIZED_KEYS_FILE.resolve())) as authorized_keys:
stored_keys = []
for authorized_key in authorized_keys:
if authorized_key.strip() != '':
stored_keys.append(authorized_key.strip())
return stored_keys
###
### Compares the list with local keys with the fetched keys from GitHub
### Return: a list of the new keys from GitHub that does not exist locally
###
def compare_key_lists(local_keys, github_keys):
new_keys = []
for key in github_keys:
key = key["key"]
if key.strip() not in local_keys:
new_keys.append(key)
return new_keys
def main():
parser = argparse.ArgumentParser(description='Fetches SSH keys from GitHub. The program will find the username in ~/.gitconfig or ask for one, if that file does not exist. \n\nIMPORTANT: This program will override all existing keys saved in ~/.authorized_keys!')
parser.add_argument('--silent', '-s', help='Will supress unnecessary terminal output. Note: the program will still ask the user for information if needed.', action="store_true")
args = parser.parse_args()
git = Git(Logger(args.silent))
# Fetch all SSH keys from GitHub
github_keys = fetch_public_keys(git.logger, git.username)
if github_keys == None:
git.logger.log("We failed to fetch SSH keys from GitHub.")
sys.exit(-1)
# Exit if the user have no keys on his GitHub account
if len(github_keys) == 0:
git.logger.log("You have no SSH keys saved on GitHub. Please save one and try again.")
sys.exit(-1)
# Ensure that ~/.ssh and ~/.ssh/authorized_keys exist
ensure_authorized_keys_file(git.logger)
# Retrieve all public keys from ~/.ssh/authorized_keys
local_keys = get_authorized_keys(git.logger)
# How many new keys?
new_keys_count = len(compare_key_lists(local_keys, github_keys))
# If there are new keys, save them in ~/.ssh/authorized_keys
if new_keys_count > 0:
with open(str(SSH_AUTHORIZED_KEYS_FILE.resolve()), 'w') as authorized_keys:
for key in github_keys:
authorized_keys.write(key["key"])
git.logger.log(str(new_keys_count) + " new keys were added to " + str(SSH_AUTHORIZED_KEYS_FILE.resolve()), True)
# Otherwise sys.exit
else:
git.logger.log("No keys were found.")
sys.exit(0)
if __name__ == '__main__':
main()