diff --git a/idp_node/mapapp/myproxy-certificate-mapapp b/idp_node/mapapp/myproxy-certificate-mapapp new file mode 100644 index 00000000..92f8748d --- /dev/null +++ b/idp_node/mapapp/myproxy-certificate-mapapp @@ -0,0 +1,10 @@ +#!/bin/bash +username=$1 +if [ X"$username" = X ]; then + # no username given + exit 1 +fi +cert_file="/var/lib/globus-connect-server/myproxy-ca/cacert.pem" +# activate virtual env +source /usr/local/conda/bin/activate esgf-pub && \ + python /esg/config/myproxy/openid_retriever.py $username $cert_file diff --git a/idp_node/mapapp/openid_retriever.py b/idp_node/mapapp/openid_retriever.py new file mode 100644 index 00000000..f3da4b29 --- /dev/null +++ b/idp_node/mapapp/openid_retriever.py @@ -0,0 +1,108 @@ +''' +Build the string for myproxy-server to use in myproxy-logon, +See http://grid.ncsa.illinois.edu/myproxy/man/myproxy-server.config.5.html +''' +import argparse +import ConfigParser +import logging +import os +import sys + +import OpenSSL +import psycopg2 + +def get_openid(args, config_parser, esgf_home): + ''' Retrieve the OpenID for a specified username ''' + logging.info("Fetching OpenID for %s", args.username) + pass_file = os.path.join(esgf_home, "config", ".esg_pg_pass") + logging.info("Retrieving pg pass from %s", pass_file) + with open(pass_file, "rb") as filep: + password = filep.read().strip() + + section = "installer.properties" + + db = config_parser.get(section, "db.database") + host = config_parser.get(section, "db.host") + port = config_parser.get(section, "db.port") + user = config_parser.get(section, "db.user") + esgf_host = config_parser.get(section, "esgf.host") + gateway = "https://{}/esgf-idp/openid/%".format(esgf_host) + + connection_params = ( + "dbname=%s user=%s password=%s host=%s port=%s" % + (db, user, password, host, port) + ) + connection_params_no_pass = ( + "dbname=%s user=%s host=%s port=%s" % + (db, user, host, port) + ) + logging.info(connection_params_no_pass) + + conn = psycopg2.connect(connection_params) + cur = conn.cursor() + query = "SELECT DISTINCT openid FROM esgf_security.user" + query += " WHERE username=%(username)s AND openid LIKE %(gateway)s " + values = { + "username": args.username, + "gateway": gateway + } + logging.info(query, values) + cur.execute(query, values) + result = cur.fetchone() + if not result: + output = "No OpenID found for {}".format(args.username) + print output + logging.error(output) + sys.exit(1) + logging.info("OpenID Success: %s", result[0]) + return result[0] + +def get_subject_line(args): + ''' Retrieve the subject line from the specified certificate file ''' + logging.info("Loading cert file: %s", args.cert_file) + with open(args.cert_file) as cert: + cert_contents = cert.read() + cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, cert_contents) + return cert.get_subject() + +def main(): + ''' + Parse arguments, setup logging, retrieve properties, + call needed functions and write new subject line to stdout + ''' + parser = argparse.ArgumentParser( + description="A script for querying the esgcet database for an OpenID, given a username" + ) + parser.add_argument("username", help="The username for which to query for the OpenID") + parser.add_argument("cert_file", help="The path to cert file to read the subject line from") + args = parser.parse_args() + + try: + esgf_home = os.environ["ESGF_HOME"] + except KeyError: + esgf_home = os.path.join(os.sep, "esg") + + logging.basicConfig( + format="%(asctime)s - %(message)s", + datefmt='%m/%d/%Y %I:%M:%S %p', + level=logging.DEBUG, + filename=os.path.join(esgf_home, "config", "myproxy", "mapapp.log"), + maxBytes=2*1024*1024 + ) + properties_file = os.path.join(esgf_home, "config", "esgf.properties") + + config_parser = ConfigParser.SafeConfigParser(allow_no_value=True) + config_parser.read(properties_file) + + openid = get_openid(args, config_parser, esgf_home) + subject_line = get_subject_line(args) + output = "/O={}/OU={}/CN={}" + output = output.format( + subject_line.O, + subject_line.OU, + openid + ) + print output + logging.info("Sent to myproxy: %s", output) + +main() diff --git a/idp_node/myproxy.py b/idp_node/myproxy.py index 716aeaa3..ca5b6b00 100644 --- a/idp_node/myproxy.py +++ b/idp_node/myproxy.py @@ -186,7 +186,7 @@ def config_myproxy_server(globus_location, install_mode="install"): esg_functions.call_binary("javac", ["-classpath", java_class_path_string, "ESGOpenIDRetriever.java"]) esg_functions.call_binary("javac", ["-classpath", java_class_path_string, "ESGGroupRetriever.java"]) - fetch_myproxy_certificate_mapapp() + copy_myproxy_certificate_mapapp() edit_pam_pgsql_conf() #-------------------- # Fetch -> pam resource file used for myproxy @@ -274,20 +274,17 @@ def copy_myproxy_server_config(config_path="/esg/config/myproxy/myproxy-server.c # Configuration File Editing Functions ############################################ -def fetch_myproxy_certificate_mapapp(): +def copy_myproxy_certificate_mapapp(): myproxy_config_dir = os.path.join(config["esg_config_dir"], "myproxy") pybash.mkdir_p(myproxy_config_dir) - with pybash.pushd(myproxy_config_dir): - mapapp_file = "myproxy-certificate-mapapp" - print "Downloading configuration file: {}".format(mapapp_file) - myproxy_dist_url_base = "{}/globus/myproxy".format(esg_property_manager.get_property("esg.root.url")) - try: - esg_functions.download_update(mapapp_file, myproxy_dist_url_base+"/{}".format(mapapp_file)) - except HTTPError: - raise - os.chmod(mapapp_file, 0751) - esg_functions.replace_string_in_file(mapapp_file, "/root/.globus/simpleCA/cacert.pem", "/var/lib/globus-connect-server/myproxy-ca/cacert.pem") + mapapp_file = "mapapp/myproxy-certificate-mapapp" + retriever_file = "mapapp/openid_retriever.py" + + os.chmod(mapapp_file, 0751) + + shutil.copy2(mapapp_file, myproxy_config_dir) + shutil.copy2(retriever_file, myproxy_config_dir) def edit_pam_pgsql_conf(): with pybash.pushd("/etc"):