2
0
mirror of https://github.com/xcat2/confluent.git synced 2025-02-04 13:02:25 +00:00

Add TPM2 support to node api key handling

This is an optional capability that image payloads may use
to use the TPM2 to protect an apikey as an alternative to
arming a weak authentication invocation
This commit is contained in:
Jarrod Johnson 2020-11-06 10:00:36 -05:00
parent 71cc0adadd
commit f7e7d05729
4 changed files with 46 additions and 5 deletions

View File

@ -36,7 +36,8 @@ unsigned char* genpasswd(int len) {
int main(int argc, char* argv[]) {
int sock, ret;
char slen;
unsigned char currlen, currtype;
unsigned char currtype;
size_t currlen;
unsigned char* passwd;
unsigned char* cryptedpass;
unsigned char* macaddr;
@ -107,10 +108,18 @@ int main(int argc, char* argv[]) {
ret = read(sock, buffer, 2);
while (buffer[0] != 255) {
currtype = buffer[0];
currlen = buffer[1];
if (currtype & 0b10000000) {
currlen = buffer[1] << 8 & buffer[2];
} else {
currlen = buffer[1];
}
memset(buffer, 0, MAXPACKET);
if (currlen > 1000) {
fprintf(stderr, "Received oversized message\n");
exit(1);
}
if (currlen) {
ret = read(sock, buffer, currlen); // Max is 255, well under MAX_PACKET
ret = read(sock, buffer, currlen); // Max is 1000, well under MAX_PACKET
}
if (currtype == 2) {
dprintf(sock, "\x03%c", currlen);
@ -118,6 +127,10 @@ int main(int argc, char* argv[]) {
slen = strlen(cryptedpass) & 0xff;
dprintf(sock, "\x04%c%s", slen, cryptedpass);
ret = write(sock, "\x00\x00", 2);
} else if (currtype == 128) {
printf("SEALED:%s", buffer);
printf("\n");
exit(0);
} else if (currtype == 5) {
printf("%s", passwd);
printf("\n");

View File

@ -129,6 +129,14 @@ node = {
'Generally this is not directly modified, but is modified '
'by the "nodedeploy" command'),
},
'deployment.sealedapikey': {
'description': 'This attribute is used by some images to save a sealed '
'version of a node apikey, so that a subsequent run with '
'same TPM2 will use the TPM2 to protect the API key rather '
'than local network verification. If this is set, then '
'an api key request will receive this if the api key grant '
'is not armed',
},
#'id': {
# 'description': ('Numeric identifier for node')
#},

View File

@ -23,6 +23,15 @@ import eventlet.green.socket as socket
import eventlet.greenpool
import os
# cred grant tlvs:
# 0, 0 - null
# 1, len, <nodename>
# 2, len, token - echo request
# 3, len, token - echo reply
# 4, len, crypted - crypted apikey
# 5, 0, accept key
# 128, len, len, key - sealed key
class CredServer(object):
def __init__(self):
self.cfm = cfm.ConfigManager(None)
@ -38,11 +47,20 @@ class CredServer(object):
client.close()
return
nodename = util.stringify(client.recv(tlv[1]))
tlv = bytearray(client.recv(2))
apiarmed = self.cfm.get_node_attributes(nodename, 'deployment.apiarmed')
tlv = bytearray(client.recv(2)) # should always be null
apiarmed = self.cfm.get_node_attributes(nodename,
['deployment.apiarmed', 'deployment.sealedapikey'])
apiarmed = apiarmed.get(nodename, {}).get('deployment.apiarmed', {}).get(
'value', None)
if not apiarmed:
if apiarmed.get(nodename, {}).get(
'deployment.sealedapikey', {}).get('value', None):
sealed = apiarmed[nodename]['deployment.sealedapikey'][
'value']
if not isintance(sealed, bytes):
sealed = sealed.encode('utf8')
reply = b'\x80' + struct.pack('>H', len(sealed) + 1) + sealed + b'\x00'
client.send(reply)
client.close()
return
if apiarmed not in ('once', 'continuous'):

View File

@ -256,6 +256,8 @@ def handle_request(env, start_response):
else:
start_response('500 Error', (('Content-Type', 'text/plain'),))
yield 'No pending profile detected, unable to accept status update'
elif env['PATH_INFO'] == '/self/savetoken':
print(repr(reqbody))
else:
start_response('404 Not Found', ())
yield 'Not found'