Blame files/keyhelper.py

Patrick Uiterwijk 6e47de
#!/usr/bin/env python
Patrick Uiterwijk 6e47de
# -*- coding: utf-8 -*-
Patrick Uiterwijk 6e47de
Patrick Uiterwijk 6e47de
"""
Patrick Uiterwijk 6e47de
 (c) 2014-2018 - Copyright Red Hat Inc
Patrick Uiterwijk 6e47de
Patrick Uiterwijk 6e47de
 Authors:
Patrick Uiterwijk 6e47de
   Patrick Uiterwijk <puiterwijk@redhat.com></puiterwijk@redhat.com>
Patrick Uiterwijk 6e47de
Patrick Uiterwijk 6e47de
"""
Patrick Uiterwijk 6e47de
Patrick Uiterwijk 6e47de
from __future__ import unicode_literals, print_function
Patrick Uiterwijk 6e47de
Patrick Uiterwijk 6e47de
import sys
Patrick Uiterwijk 6e47de
import os
Patrick Uiterwijk 6e47de
Patrick Uiterwijk 6e47de
# Since this is run by sshd, we don't have a way to set environment
Patrick Uiterwijk 6e47de
# variables ahead of time
Patrick Uiterwijk 6e47de
if "PAGURE_CONFIG" not in os.environ and os.path.exists(
Patrick Uiterwijk 6e47de
    "/etc/pagure/pagure.cfg"
Patrick Uiterwijk 6e47de
):
Patrick Uiterwijk 6e47de
    os.environ["PAGURE_CONFIG"] = "/etc/pagure/pagure.cfg"
Patrick Uiterwijk 6e47de
Patrick Uiterwijk 6e47de
# Here starts the code
Patrick Uiterwijk 6e47de
import pagure
Patrick Uiterwijk 6e47de
import pagure.lib
Patrick Uiterwijk 6e47de
from pagure.config import config as pagure_config
Patrick Uiterwijk 6e47de
from pagure.lib.model import User, DeployKey
Patrick Uiterwijk 6e47de
Patrick Uiterwijk 6e47de
Patrick Uiterwijk 6e47de
# Get the arguments
Patrick Uiterwijk 6e47de
# Expect sshd config:
Patrick Uiterwijk 6e47de
# AuthorizedKeysCommand: <scriptpath> "%u" "%h" "%t" "%f"</scriptpath>
Patrick Uiterwijk 6e47de
# <us> <username> <homedir> <keytype> <fingerprint></fingerprint></keytype></homedir></username></us>
Patrick Uiterwijk 6e47de
# At this moment, we ignore the homedir and fingerprint, since looking
Patrick Uiterwijk 6e47de
# up a key by fingerprint would require some model changes (ssh keys would
Patrick Uiterwijk 6e47de
#   need to be stored in a fashion like DeployKeys).
Patrick Uiterwijk 6e47de
# But to not break installations in the future, we should ask installations
Patrick Uiterwijk 6e47de
# to set up sshd in a way that it will work if we use them in the future.
Patrick Uiterwijk 6e47de
if len(sys.argv) < 5:
Patrick Uiterwijk 6e47de
    print("Invalid call, too few arguments", file=sys.stderr)
Patrick Uiterwijk 6e47de
    sys.exit(1)
Patrick Uiterwijk 6e47de
Patrick Uiterwijk 6e47de
Patrick Uiterwijk 6e47de
username, userhome, keytype, fingerprint = sys.argv[1:5]
Patrick Uiterwijk 6e47de
username_lookup = pagure_config["SSH_KEYS_USERNAME_LOOKUP"]
Patrick Uiterwijk 6e47de
expect_username = pagure_config["SSH_KEYS_USERNAME_EXPECT"]
Patrick Uiterwijk 6e47de
Patrick Uiterwijk 6e47de
Patrick Uiterwijk e95068
if username in pagure_config["SSH_KEYS_USERNAME_FORBIDDEN"]:
Patrick Uiterwijk e95068
    print("User is forbidden for keyhelper.", file=sys.stderr)
Patrick Uiterwijk e95068
    sys.exit(1)
Patrick Uiterwijk e95068
Patrick Uiterwijk e95068
Patrick Uiterwijk 6e47de
if not username_lookup:
Patrick Uiterwijk 6e47de
    if not expect_username:
Patrick Uiterwijk 6e47de
        print("Pagure keyhelper configured incorrectly", file=sys.stderr)
Patrick Uiterwijk 6e47de
        sys.exit(1)
Patrick Uiterwijk 6e47de
Patrick Uiterwijk 6e47de
    if username != expect_username:
Patrick Uiterwijk 6e47de
        # Nothing to look up, this user is not git-related
Patrick Uiterwijk 6e47de
        sys.exit(0)
Patrick Uiterwijk 6e47de
Patrick Uiterwijk 6e47de
Patrick Uiterwijk 6e47de
session = pagure.lib.create_session(pagure_config["DB_URL"])
Patrick Uiterwijk 6e47de
if not session:
Patrick Uiterwijk 6e47de
    print("Unable to get database access")
Patrick Uiterwijk 6e47de
    sys.exit(1)
Patrick Uiterwijk 6e47de
Patrick Uiterwijk 6e47de
Patrick Uiterwijk 6e47de
# First try to figure out if this is a deploykey.
Patrick Uiterwijk 6e47de
# We can look those up very quickly, since those are already
Patrick Uiterwijk 6e47de
# indexed by key fingerprint.
Patrick Uiterwijk 6e47de
query = session.query(DeployKey).filter(
Patrick Uiterwijk 6e47de
    DeployKey.ssh_search_key == fingerprint
Patrick Uiterwijk 6e47de
)
Patrick Uiterwijk 6e47de
for dkey in query.all():
Patrick Uiterwijk 6e47de
    keyenv = {
Patrick Uiterwijk 6e47de
        "username": "deploykey_%s_%s"
Patrick Uiterwijk 6e47de
        % (werkzeug.secure_filename(dkey.project.fullname), dkey.id)
Patrick Uiterwijk 6e47de
    }
Patrick Uiterwijk 6e47de
    print(
Patrick Uiterwijk 6e47de
        "%s %s"
Patrick Uiterwijk 6e47de
        % (pagure_config["SSH_KEYS_OPTIONS"] % keyenv, dkey.public_ssh_key)
Patrick Uiterwijk 6e47de
    )
Patrick Uiterwijk 6e47de
    sys.exit(0)
Patrick Uiterwijk 6e47de
Patrick Uiterwijk 6e47de
Patrick Uiterwijk 6e47de
# Now look if it's a normal user
Patrick Uiterwijk 6e47de
query = session.query(User)
Patrick Uiterwijk 6e47de
if username_lookup:
Patrick Uiterwijk 6e47de
    query = query.filter(User.user == username)
Patrick Uiterwijk 6e47de
Patrick Uiterwijk 6e47de
for user in query.all():
Patrick Uiterwijk 6e47de
    for key in user.public_ssh_key.split("\n"):
Patrick Uiterwijk 6e47de
        # Make slightly more sane
Patrick Uiterwijk 6e47de
        key = key.strip()
Patrick Uiterwijk 6e47de
        # Check if this could even be a valid key
Patrick Uiterwijk 6e47de
        key = key.split(" ")
Patrick Uiterwijk 6e47de
        # Should be at the very least ["<keytype>", "</keytype>
Patrick Uiterwijk 6e47de
        if len(key) < 2:
Patrick Uiterwijk 6e47de
            continue
Patrick Uiterwijk 6e47de
        # If the keytype doesn't match, just ignore the key
Patrick Uiterwijk 6e47de
        if key[0] != keytype:
Patrick Uiterwijk 6e47de
            continue
Patrick Uiterwijk 6e47de
        # Build up some variables to use in the ssh key options
Patrick Uiterwijk 6e47de
        keyenv = {"username": user.username}
Patrick Uiterwijk 6e47de
        # This is a possible key, print it
Patrick Uiterwijk 6e47de
        print(
Patrick Uiterwijk 6e47de
            "%s %s %s"
Patrick Uiterwijk 6e47de
            % (pagure_config["SSH_KEYS_OPTIONS"] % keyenv, key[0], key[1])
Patrick Uiterwijk 6e47de
        )