Merge pull request #30 from jamesii-b/v1.01/stable

Feat: Implemented Known hosts via CLI & Fix:  Permissons for ssh-cert
This commit is contained in:
2026-04-26 22:55:07 +08:00
committed by GitHub
+58 -5
View File
@@ -369,7 +369,12 @@ def request_certificate(org_id=None):
json_result = response.json().get('data', response.json())
with open(CERT_FILE_PATH, 'w') as f:
f.write(json_result['certificate'])
os.chmod(CERT_FILE_PATH, 0o600)
try:
os.chmod(CERT_FILE_PATH, 0o600)
except OSError:
pass
logger.info(f"Certificate signed successfully, located at {CERT_FILE_PATH}")
logger.info(f"Valid for principals: {', '.join(json_result.get('principals', principals))}")
@@ -607,6 +612,51 @@ def checkCert():
logger.warning("Certificate is not valid, renewal required")
return 1
def install_known_hosts():
"""Fetch Host CA from the upstream server and install it into ~/.ssh/known_hosts."""
try:
response = requests.get(f"{SIGN_URL}/api/v1/ssh/ca/public-key?ca_type=host", headers=auth_headers())
if response.status_code != 200:
logger.error(f"Failed to fetch host CA public key: {response.status_code} - {response.text}")
exit(1)
ca_data = response.json().get('data', {})
public_key = ca_data.get('public_key', '').strip()
if not public_key:
logger.error("No public key found in the response.")
exit(1)
known_hosts_path = os.path.expanduser("~/.ssh/known_hosts")
ssh_dir = os.path.dirname(known_hosts_path)
if not os.path.exists(ssh_dir):
os.makedirs(ssh_dir, mode=0o700)
# Standard format for OpenSSH cert-authority
entry = f"@cert-authority * {public_key}\n"
# Check if already present
if os.path.exists(known_hosts_path):
with open(known_hosts_path, 'r') as f:
content = f.read()
if public_key in content:
logger.info("Host CA public key is already in ~/.ssh/known_hosts. No changes made.")
return
with open(known_hosts_path, 'a') as f:
f.write(entry)
try:
os.chmod(known_hosts_path, 0o600)
except OSError:
pass # May not have permission to chmod if owned by root, but let's try
logger.info(f"Successfully installed Host CA public key to {known_hosts_path} for all hosts (*)")
except Exception as e:
logger.error(f"Error during Host CA installation: {e}")
exit(1)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Sign an SSH key via a web service')
parser.add_argument("-k", "--ssh-key", type=argparse.FileType('rb'), dest="sshkeyfile", help="Add an SSH Public Key to your user profile in gatehouse")
@@ -617,13 +667,12 @@ if __name__ == "__main__":
parser.add_argument("--clear-cache", action='store_true', default=False, help="Remove the cached authentication token")
parser.add_argument("--remove-key", nargs='?', const='', metavar='KEY_ID', help="Remove an SSH key from your profile. Omit KEY_ID to pick interactively.")
parser.add_argument("--list-keys", action='store_true', default=False, help="List SSH keys in your profile")
parser.add_argument("--list-orgs", action='store_true', default=False, help="List all organizations you are a member of")
parser.add_argument("--org-id", metavar='ORG_ID', help="Specify organization ID for certificate signing (required if member of multiple orgs)")
parser.add_argument("--install-known-hosts", action='store_true', default=False, help="Fetch Host CA public key and install into ~/.ssh/known_hosts")
args = parser.parse_args()
if not (args.check_cert or args.request_cert or args.add_key or args.clear_cache
or args.remove_key is not None or args.list_keys or args.list_orgs):
parser.error("At least one of --check-cert, --request-cert, --add-key, --list-keys, --remove-key, --list-orgs, or --clear-cache must be provided.")
or args.remove_key is not None or args.list_keys or args.install_known_hosts):
parser.error("At least one of --check-cert, --request-cert, --add-key, --list-keys, --remove-key, --clear-cache, or --install-known-hosts must be provided.")
# Retrieve SSH key from environment variables if not provided via CLI
@@ -677,6 +726,10 @@ if __name__ == "__main__":
add_ssh_key(ssh_key_file)
exit(0)
if args.install_known_hosts:
request_token()
install_known_hosts()
exit(0)
if args.request_cert:
request_token()