diff --git a/files/static-vendor-data.json b/files/static-vendor-data.json index 93f251f..e5b0850 100644 --- a/files/static-vendor-data.json +++ b/files/static-vendor-data.json @@ -1 +1 @@ -{"cloud-init": "#cloud-config\nmounts:\n - [ /dev/disk/by-label/config-2, /mnt/config ]\npackages:\n - python\n - python-requests\nwrite_files:\n - path: /root/setup-ssh.py\n permissions: '0700'\n owner: root:root\n content: |\n print 'Importing packages'\n import json\n import requests\n import os\n import subprocess\n import uuid\n def getVendordataFromConfigDrive():\n path = '/mnt/config/openstack/latest/vendor_data2.json'\n with open(path, 'r') as f:\n json_string = f.read()\n return json.loads(json_string)\n def getInstanceAndProjectIdFromConfigDrive():\n path = '/mnt/config/openstack/latest/meta_data.json'\n with open(path, 'r') as f:\n json_string = f.read()\n metadata = json.loads(json_string)\n assert 'uuid' in metadata\n assert 'project_id' in metadata\n return str(uuid.UUID(metadata['uuid'], version=4)), str(uuid.UUID(metadata['project_id'], version=4))\n print 'Getting vendordata from ConfigDrive'\n vendordata = getVendordataFromConfigDrive()\n print 'Getting instance and project IDs'\n instance_id, project_id = getInstanceAndProjectIdFromConfigDrive()\n assert 'tatu' in vendordata\n tatu = vendordata['tatu']\n assert 'token' in tatu\n assert 'auth_pub_key_user' in tatu\n assert 'principals' in tatu\n principals = tatu['principals'].split(',')\n with open('/etc/ssh/ssh_host_rsa_key.pub', 'r') as f:\n host_key_pub = f.read()\n server = 'http://172.24.4.1:18322'\n hostcert_request = {\n 'token_id': tatu['token'],\n 'host_id': instance_id,\n 'key.pub': host_key_pub\n }\n print 'Request the host certificate.'\n response = requests.post(\n # Hard-coded SSHaaS API address will only work for devstack and requires\n # routing and SNAT or DNAT.\n # This eventually needs to be either:\n # 1) 169.254.169.254 if there's a SSHaaS-proxy; OR\n # 2) the real address of the API, possibly supplied in the vendordata and\n # still requiring routing and SNAT or DNAT.\n server + '/noauth/hostcerts',\n data=json.dumps(hostcert_request)\n )\n print 'Got the host certificate: {}'.format(response.content)\n assert response.status_code == 201\n assert 'location' in response.headers\n location = response.headers['location']\n # No need to GET the host cert - it's returned in the POST\n #response = requests.get(server + location)\n hostcert = json.loads(response.content)\n assert 'host_id' in hostcert\n assert hostcert['host_id'] == instance_id\n assert 'fingerprint' in hostcert\n assert 'auth_id' in hostcert\n auth_id = str(uuid.UUID(hostcert['auth_id'], version=4))\n assert auth_id == project_id\n assert 'key-cert.pub' in hostcert\n print 'Begin writing files.'\n # Write the host's certificate\n with open('/etc/ssh/ssh_host_rsa_key-cert.pub', 'w') as f:\n f.write(hostcert['key-cert.pub'])\n # Write the authorized principals file\n os.mkdir('/etc/ssh/auth_principals')\n with open('/etc/ssh/auth_principals/ubuntu', 'w') as f:\n for p in principals:\n f.write(p + os.linesep)\n # Write the User CA public key file\n with open('/etc/ssh/ca_user.pub', 'w') as f:\n f.write(tatu['auth_pub_key_user'])\n print 'All tasks completed.'\nruncmd:\n - python /root/setup-ssh.py > /var/log/setup-ssh.log 2>&1\n - sed -i -e '$aTrustedUserCAKeys /etc/ssh/ca_user.pub' /etc/ssh/sshd_config\n - sed -i -e '$aAuthorizedPrincipalsFile /etc/ssh/auth_principals/%u' /etc/ssh/sshd_config\n - sed -i -e '$aHostCertificate /etc/ssh/ssh_host_rsa_key-cert.pub' /etc/ssh/sshd_config\n - systemctl restart ssh\n"} +{"cloud-init": "#cloud-config\nmounts:\n - [ /dev/disk/by-label/config-2, /mnt/config ]\npackages:\n - python\n - python-requests\nwrite_files:\n - path: /root/setup-ssh.py\n permissions: '0700'\n owner: root:root\n content: |\n print 'Importing packages'\n import json\n import requests\n import os\n import subprocess\n import uuid\n def getVendordataFromConfigDrive():\n path = '/mnt/config/openstack/latest/vendor_data2.json'\n with open(path, 'r') as f:\n json_string = f.read()\n return json.loads(json_string)\n def getInstanceAndProjectIdFromConfigDrive():\n path = '/mnt/config/openstack/latest/meta_data.json'\n with open(path, 'r') as f:\n json_string = f.read()\n metadata = json.loads(json_string)\n assert 'uuid' in metadata\n assert 'project_id' in metadata\n return str(uuid.UUID(metadata['uuid'], version=4)), str(uuid.UUID(metadata['project_id'], version=4))\n print 'Getting vendordata from ConfigDrive'\n vendordata = getVendordataFromConfigDrive()\n print 'Getting instance and project IDs'\n instance_id, project_id = getInstanceAndProjectIdFromConfigDrive()\n assert 'tatu' in vendordata\n tatu = vendordata['tatu']\n assert 'token' in tatu\n assert 'auth_pub_key_user' in tatu\n assert 'principals' in tatu\n principals = tatu['principals'].split(',')\n with open('/etc/ssh/ssh_host_rsa_key.pub', 'r') as f:\n host_key_pub = f.read()\n server = 'http://172.24.4.1:18322'\n hostcert_request = {\n 'token_id': tatu['token'],\n 'host_id': instance_id,\n 'pub_key': host_key_pub\n }\n print 'Request the host certificate.'\n response = requests.post(\n # Hard-coded SSHaaS API address will only work for devstack and requires\n # routing and SNAT or DNAT.\n # This eventually needs to be either:\n # 1) 169.254.169.254 if there's a SSHaaS-proxy; OR\n # 2) the real address of the API, possibly supplied in the vendordata and\n # still requiring routing and SNAT or DNAT.\n server + '/noauth/hostcerts',\n data=json.dumps(hostcert_request)\n )\n print 'Got the host certificate: {}'.format(response.content)\n assert response.status_code == 201\n assert 'location' in response.headers\n location = response.headers['location']\n # No need to GET the host cert - it's returned in the POST\n #response = requests.get(server + location)\n hostcert = json.loads(response.content)\n assert 'host_id' in hostcert\n assert hostcert['host_id'] == instance_id\n assert 'fingerprint' in hostcert\n assert 'auth_id' in hostcert\n auth_id = str(uuid.UUID(hostcert['auth_id'], version=4))\n assert auth_id == project_id\n assert 'cert' in hostcert\n print 'Begin writing files.'\n # Write the host's certificate\n with open('/etc/ssh/ssh_host_rsa_key-cert.pub', 'w') as f:\n f.write(hostcert['cert'])\n # Write the authorized principals file\n os.mkdir('/etc/ssh/auth_principals')\n with open('/etc/ssh/auth_principals/ubuntu', 'w') as f:\n for p in principals:\n f.write(p + os.linesep)\n # Write the User CA public key file\n with open('/etc/ssh/ca_user.pub', 'w') as f:\n f.write(tatu['auth_pub_key_user'])\n print 'All tasks completed.'\nruncmd:\n - python /root/setup-ssh.py > /var/log/setup-ssh.log 2>&1\n - sed -i -e '$aTrustedUserCAKeys /etc/ssh/ca_user.pub' /etc/ssh/sshd_config\n - sed -i -e '$aAuthorizedPrincipalsFile /etc/ssh/auth_principals/%u' /etc/ssh/sshd_config\n - sed -i -e '$aHostCertificate /etc/ssh/ssh_host_rsa_key-cert.pub' /etc/ssh/sshd_config\n - systemctl restart ssh\n"} diff --git a/files/user-cloud-config b/files/user-cloud-config index faa8d89..b9e6ea8 100644 --- a/files/user-cloud-config +++ b/files/user-cloud-config @@ -44,7 +44,7 @@ write_files: hostcert_request = { 'token_id': tatu['token'], 'host_id': instance_id, - 'key.pub': host_key_pub + 'pub_key': host_key_pub } print 'Request the host certificate.' response = requests.post( @@ -70,11 +70,11 @@ write_files: assert 'auth_id' in hostcert auth_id = str(uuid.UUID(hostcert['auth_id'], version=4)) assert auth_id == project_id - assert 'key-cert.pub' in hostcert + assert 'cert' in hostcert print 'Begin writing files.' # Write the host's certificate with open('/etc/ssh/ssh_host_rsa_key-cert.pub', 'w') as f: - f.write(hostcert['key-cert.pub']) + f.write(hostcert['cert']) # Write the authorized principals file os.mkdir('/etc/ssh/auth_principals') with open('/etc/ssh/auth_principals/root', 'w') as f: diff --git a/files/user-cloud-config2 b/files/user-cloud-config2 index 90723eb..ff7628b 100644 --- a/files/user-cloud-config2 +++ b/files/user-cloud-config2 @@ -33,7 +33,7 @@ write_files: echo principals=$principals host_pub_key=$(cat /etc/ssh/ssh_host_rsa_key.pub) echo host public key is $host_pub_key - data=$(echo {\"token_id\": \"$token\", \"host_id\": \"$host_id\", \"key.pub\": \"$host_pub_key\"}) + data=$(echo {\"token_id\": \"$token\", \"host_id\": \"$host_id\", \"pub_key\": \"$host_pub_key\"}) echo $data > /tmp/tatu_cert_request.json url=http://169.254.169.254/noauth/hostcerts echo url=$url @@ -45,7 +45,7 @@ write_files: exit 1 fi echo Tatu response is $response - cert=$(echo $response | grep -Po 'key-cert.pub": "\K[^"]*') + cert=$(echo $response | grep -Po 'cert": "\K[^"]*') cert=${cert%%\\n} # TODO: fix the trailing \n on the server side. echo $cert > /etc/ssh/ssh_host_rsa_key-cert.pub mkdir -p /etc/ssh/auth_principals diff --git a/scripts/get-user-cert b/scripts/get-user-cert index 1cf24d9..f53ba8f 100755 --- a/scripts/get-user-cert +++ b/scripts/get-user-cert @@ -49,7 +49,7 @@ server = args.tatu_url user = { 'user_id': user_id, 'auth_id': auth_id, - 'key.pub': pubkeytext + 'pub_key': pubkeytext } response = requests.post( @@ -65,4 +65,4 @@ location = response.headers['location'] response = requests.get(server + location) usercert = json.loads(response.content) -print usercert['key-cert.pub'] +print usercert['cert'] diff --git a/tatu/api/models.py b/tatu/api/models.py index 2025fe9..c4a6d37 100644 --- a/tatu/api/models.py +++ b/tatu/api/models.py @@ -97,8 +97,8 @@ class Authorities(object): host_pub_key = host_key.publickey().exportKey('OpenSSH') items.append({ 'auth_id': auth.auth_id, - 'user_key.pub': user_pub_key, - 'host_key.pub': host_pub_key, + 'ca_user_pub': user_pub_key, + 'ca_host_pub': host_pub_key, }) body = {'CAs': items} resp.body = json.dumps(body) @@ -118,8 +118,8 @@ class Authority(object): host_pub_key = host_key.publickey().exportKey('OpenSSH') body = { 'auth_id': auth_id, - 'user_key.pub': user_pub_key, - 'host_key.pub': host_pub_key + 'ca_user_pub': user_pub_key, + 'ca_host_pub': host_pub_key } resp.body = json.dumps(body) resp.status = falcon.HTTP_OK @@ -129,7 +129,7 @@ def _userAsDict(user): 'user_id': user.user_id, 'fingerprint': user.fingerprint, 'auth_id': user.auth_id, - 'key-cert.pub': user.cert, + 'cert': user.cert, 'revoked': user.revoked, 'serial': user.serial, } @@ -143,7 +143,7 @@ class UserCerts(object): self.session, req.body['user_id'], req.body['auth_id'], - req.body['key.pub'] + req.body['pub_key'] ) except KeyError as e: raise falcon.HTTPBadRequest(str(e)) @@ -178,7 +178,7 @@ def hostToJson(host): 'host_id': host.host_id, 'fingerprint': host.fingerprint, 'auth_id': host.auth_id, - 'key-cert.pub': host.cert, + 'cert': host.cert, }) @@ -192,7 +192,7 @@ class HostCerts(object): self.session, req.body['token_id'], req.body['host_id'], - req.body['key.pub'] + req.body['pub_key'] ) except KeyError as e: raise falcon.HTTPBadRequest(str(e)) @@ -209,7 +209,7 @@ class HostCerts(object): 'host_id': host.host_id, 'fingerprint': host.fingerprint, 'auth_id': host.auth_id, - 'key-cert.pub': host.cert, + 'cert': host.cert, 'hostname': host.hostname, } if CONF.tatu.use_pat_bastions: diff --git a/tatu/ftests/test_api.py b/tatu/ftests/test_api.py index 8fd241a..8e9e330 100644 --- a/tatu/ftests/test_api.py +++ b/tatu/ftests/test_api.py @@ -33,7 +33,7 @@ def host_request(token, host, pub_key): return { 'token_id': token, 'host_id': host, - 'key.pub': pub_key + 'pub_key': pub_key } @@ -52,9 +52,9 @@ def test_host_certificate_generation(): auth = json.loads(response.content) assert 'auth_id' in auth assert auth['auth_id'] == project_id - assert 'user_key.pub' in auth - assert 'host_key.pub' in auth - ca_user = auth['user_key.pub'] + assert 'ca_user_pub' in auth + assert 'ca_host_pub' in auth + ca_user = auth['ca_user_pub'] key = RSA.generate(2048) pub_key = key.publickey().exportKey('OpenSSH') @@ -110,4 +110,4 @@ def test_host_certificate_generation(): assert 'auth_id' in hostcert auth_id = str(uuid.UUID(hostcert['auth_id'], version=4)) assert auth_id == project_id - assert 'key-cert.pub' in hostcert + assert 'cert' in hostcert diff --git a/tatu/tests/test_app.py b/tatu/tests/test_app.py index a5a6ee0..4b6594e 100644 --- a/tatu/tests/test_app.py +++ b/tatu/tests/test_app.py @@ -108,10 +108,10 @@ def test_get_authority(client): assert response.status == falcon.HTTP_OK body = json.loads(response.content) assert 'auth_id' in body - assert 'user_key.pub' in body + assert 'ca_user_pub' in body global auth_user_pub_key - auth_user_pub_key = body['user_key.pub'] - assert 'host_key.pub' in body + auth_user_pub_key = body['ca_user_pub'] + assert 'ca_host_pub' in body assert 'user_key' not in body assert 'host_key' not in body @@ -130,7 +130,7 @@ def user_request(auth=auth_id, user_id=user_id, pub_key=user_pub_key): return { 'user_id': user_id, 'auth_id': auth, - 'key.pub': pub_key + 'pub_key': pub_key } @@ -157,7 +157,7 @@ def test_post_user(client): location = response.headers['location'].split('/') assert location[1] == 'usercerts' assert location[2] == body['user_id'] - assert location[3] == sshpubkeys.SSHKey(body['key.pub']).hash_md5() + assert location[3] == sshpubkeys.SSHKey(body['pub_key']).hash_md5() @pytest.mark.dependency(depends=['test_post_user']) @@ -169,7 +169,7 @@ def test_get_user(client): assert 'user_id' in body assert 'fingerprint' in body assert 'auth_id' in body - assert 'key-cert.pub' in body + assert 'cert' in body assert body['auth_id'] == auth_id @@ -227,7 +227,7 @@ def host_request(token, host=host_id, pub_key=host_pub_key): return { 'token_id': token, 'host_id': host, - 'key.pub': pub_key + 'pub_key': pub_key } @@ -394,7 +394,7 @@ def test_get_host(client): assert 'host_id' in body assert 'fingerprint' in body assert 'auth_id' in body - assert 'key-cert.pub' in body + assert 'cert' in body assert body['host_id'] == host_id assert body['fingerprint'] == host_fingerprint assert body['auth_id'] == auth_id