Blob Blame History Raw
#!/usr/bin/python
# -*- coding: utf-8 -*-
from __future__ import print_function

import os
import pwd
import sys
import optparse
import requests

from getpass import getpass

from centos import CentOSUserCert
from centos import defaults

try:
    import urlparse
except ImportError:
    import urllib.parse as urlparse


def download_cert(username, password, topurl=None):
    if not topurl:
        topurl = defaults.FAS_TOPURL

    splittopurl = urlparse.urlsplit(topurl)

    usercertpath = os.path.join(splittopurl.path, 'user/dogencert')
    params = {'user_name': username, 'password': password, 'login': 'Login'}

    userspliturl = urlparse.SplitResult(splittopurl.scheme,
                                        splittopurl.netloc,
                                        usercertpath,
                                        None,
                                        None)

    servercapath = os.path.join(splittopurl.path, 'ca/ca-cert.pem')
    servercaspliturl = urlparse.SplitResult(splittopurl.scheme,
                                            splittopurl.netloc,
                                            servercapath,
                                            None,
                                            None)

    userurl = urlparse.urlunsplit(userspliturl)
    servercaurl = urlparse.urlunsplit(servercaspliturl)

    certfile = os.path.expanduser(defaults.USER_CERT_FILE)
    if os.path.exists(certfile):
        # Delete file in case we are changing its mode
        os.unlink(certfile)
    flags = os.O_WRONLY | os.O_CREAT
    mode = 0o600
    with os.fdopen(os.open(certfile, flags, mode), 'w') as usercertfile:
        r = requests.post(userurl, params=params)
        try:
            r.raise_for_status()
        except requests.exceptions.HTTPError as e:
            print("""Could not generate certificate!
Response Code: {0}
Message: {1}""".format(e.response.status_code, e.response.reason).strip())
            sys.exit(1)

        response = r.text
        usercertfile.write(response)

    with open(os.path.expanduser(defaults.SERVER_CA_CERT_FILE), 'w') as servercacertfile:
        r = requests.get(servercaurl)
        try:
            r.raise_for_status()
        except requests.exceptions.HTTPError as e:
            print("""Could not download CA Certificate!
Response Code: {0}
Message: {1}""".format(e.response.status_code, e.response.reason).strip())
            sys.exit(1)

        response = r.text
        servercacertfile.write(response)

    # for now upload-ca.cert is the same as the server-ca cert. let's link them here
    if os.path.exists(os.path.expanduser(defaults.UPLOAD_CA_CERT_FILE)):
        os.unlink(os.path.expanduser(defaults.UPLOAD_CA_CERT_FILE))

    os.symlink(os.path.expanduser(defaults.SERVER_CA_CERT_FILE),
               os.path.expanduser(defaults.UPLOAD_CA_CERT_FILE))


def main(opts):

    if not opts.certfile:
        certfile = defaults.USER_CERT_FILE
    else:
        certfile = opts.certfile

    if opts.username and not opts.verifycert:
        username = opts.username
    else:
        try:
            cert = CentOSUserCert(certfile)
            username = cert.CN
        except IOError as e:
            if opts.verifycert:
                print("{0}: {1}".format(os.path.expanduser(certfile), e.strerror))
                exit(1)
            username = pwd.getpwuid(os.geteuid())[0]

    if opts.verifycert:
        if not cert.valid:
            print("Your certificate is not valid")
            sys.exit(1)
        else:
            print("Your certificate is valid")
            sys.exit(0)

    if opts.newcert:
        password = getpass('ACO Password: ')
        download_cert(username, password)


if __name__ == '__main__':
    parser = optparse.OptionParser(usage="%prog [OPTIONS] ")
    parser.add_option('-u', '--username', action='store', dest='username',
                      default=False, help="ACO Username.")
    parser.add_option('-n', '--new-cert', action='store_true', dest='newcert',
                      default=False, help="Generate a new User Certificate.")
    parser.add_option('-f', '--file', action='store', dest='certfile',
                      default=None, help="User Certificate.")
    parser.add_option('-v', '--verify-cert', action='store_true', dest='verifycert',
                      default=False, help="Verify Certificate.")
    opts, args = parser.parse_args()

    if not opts.newcert and not opts.verifycert:
        print("Must specify one of arguments: -v or -n")
        parser.print_help()
        sys.exit(1)

    main(opts)