From ae4098da226020a09f16fabaf793a965c0551730 Mon Sep 17 00:00:00 2001 From: pfeairheller Date: Wed, 31 Jan 2024 21:57:53 -0500 Subject: [PATCH] Lots of changes, not really sure. --- Dockerfile | 9 +- schema/ecr-vlei-credential.json | 1 + scripts/ecr-data.json | 5 + scripts/ecr-issue.sh | 20 +++ scripts/{auth-scripts.sh => env.sh} | 0 scripts/kassh.sh | 2 +- scripts/keri/cf/demo-witness-oobis.json | 6 +- scripts/keri/cf/main/wan.json | 9 ++ scripts/keri/cf/main/wes.json | 9 ++ scripts/keri/cf/main/wil.json | 9 ++ scripts/keri/cf/main/wit.json | 9 ++ scripts/keri/cf/main/wub.json | 9 ++ scripts/keri/cf/main/wyz.json | 9 ++ src/kassh/core/handling.py | 156 +++++++++++++++++------- 14 files changed, 206 insertions(+), 47 deletions(-) create mode 100644 schema/ecr-vlei-credential.json create mode 100644 scripts/ecr-data.json create mode 100755 scripts/ecr-issue.sh rename scripts/{auth-scripts.sh => env.sh} (100%) diff --git a/Dockerfile b/Dockerfile index b63c58d..da1c85d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,15 +1,20 @@ -FROM gleif/keri:1.0.0 +FROM weboftrust/keri:orig RUN apt-get update && apt-get install -y openssh-server -RUN mkdir /var/run/sshd +RUN groupadd sftp_users +RUN mkdir /var/run/sshd +RUN mkdir -p /data +RUN chown -R root:sftp_users /data/ RUN echo 'root:PASSWORD' | chpasswd RUN sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd +RUN echo $'Match Group sftp_users\n\tForceCommand internal-sftp' >> /etc/ssh/sshd_config + EXPOSE 22 WORKDIR /usr/local/var diff --git a/schema/ecr-vlei-credential.json b/schema/ecr-vlei-credential.json new file mode 100644 index 0000000..88ce6c0 --- /dev/null +++ b/schema/ecr-vlei-credential.json @@ -0,0 +1 @@ +{"$id": "EM_FCDJGw6etiKHT7gQTFbWdq45MfwIrzbu_lyaupdhr", "$schema": "http://json-schema.org/draft-07/schema#", "title": "Legal Entity Engagement Context Role vLEI Credential", "description": "A vLEI Role Credential issued to representatives of a Legal Entity in other than official roles but in functional or other context of engagement", "type": "object", "credentialType": "LegalEntityEngagementContextRolevLEICredential", "properties": {"v": {"description": "Version", "type": "string"}, "d": {"description": "Credential SAID", "type": "string"}, "u": {"description": "One time use nonce", "type": "string"}, "i": {"description": "GLEIF Issuee AID", "type": "string"}, "ri": {"description": "Credential status registry", "type": "string"}, "s": {"description": "Schema SAID", "type": "string"}, "a": {"oneOf": [{"description": "Attributes block SAID", "type": "string"}, {"$id": "EDv4wiOMHE125CXu-EuOd0YRXz-AgpLilJfjoODFqtHD", "description": "Attributes block", "type": "object", "properties": {"d": {"description": "Attributes block SAID", "type": "string"}, "u": {"description": "A salty nonce", "type": "string"}, "i": {"description": "Person Issuee AID", "type": "string"}, "dt": {"description": "Issuance date time", "type": "string", "format": "date-time"}, "LEI": {"description": "LEI of the Legal Entity", "type": "string", "format": "ISO 17442"}, "personLegalName": {"description": "Recipient name as provided during identity assurance", "type": "string"}, "engagementContextRole": {"description": "Role description i.e. 'Head of Standards'", "type": "string"}}, "additionalProperties": false, "required": ["i", "dt", "LEI", "personLegalName", "engagementContextRole"]}]}}, "additionalProperties": false, "required": ["i", "ri", "s", "d"]} \ No newline at end of file diff --git a/scripts/ecr-data.json b/scripts/ecr-data.json new file mode 100644 index 0000000..0d62ac8 --- /dev/null +++ b/scripts/ecr-data.json @@ -0,0 +1,5 @@ +{ + "LEI": "O2RNE8IBXP4R0TD8PU41", + "personLegalName": "Monsieur Duchmol", + "engagementContextRole": "EBA Document Submitter" +} \ No newline at end of file diff --git a/scripts/ecr-issue.sh b/scripts/ecr-issue.sh new file mode 100755 index 0000000..7232627 --- /dev/null +++ b/scripts/ecr-issue.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +kli init --name issuer --salt 0ACDEyMzQ1Njc4OWxtbm9aBc --nopasscode --config-dir ${KASSH_SCRIPT_DIR} --config-file demo-witness-oobis +kli incept --name issuer --alias issuer --file ${KASSH_SCRIPT_DIR}/incept.json + +kli init --name holder --salt 0ACDEyMzQ1Njc4OWxtbm9qWc --nopasscode --config-dir ${KASSH_SCRIPT_DIR} --config-file demo-witness-oobis +kli incept --name holder --alias holder --file ${KASSH_SCRIPT_DIR}/incept.json + +kli oobi resolve --name issuer --oobi-alias holder --oobi http://127.0.0.1:5642/oobi/EAa46iafkH0lpUkn7YGZ3kdvC9nNUiImhLNlODiw86AI/witness/BBilc4-L3tFUnfM_wJr4S4OJanAv_VmF_dJNN6vkf2Ha +kli oobi resolve --name holder --oobi-alias issuer --oobi http://127.0.0.1:5642/oobi/EImOExnAuY3_6C2J48HhGytUDAvQEB2Ypy6pLs0GxfBR/witness/BBilc4-L3tFUnfM_wJr4S4OJanAv_VmF_dJNN6vkf2Ha +kli oobi resolve --name issuer --oobi-alias issuer --oobi http://127.0.0.1:7723/oobi/EM_FCDJGw6etiKHT7gQTFbWdq45MfwIrzbu_lyaupdhr +kli oobi resolve --name holder --oobi-alias holder --oobi http://127.0.0.1:7723/oobi/EM_FCDJGw6etiKHT7gQTFbWdq45MfwIrzbu_lyaupdhr + +kli vc registry incept --name issuer --alias issuer --registry-name vLEI + +kli vc issue --name issuer --alias issuer --registry-name vLEI --schema EM_FCDJGw6etiKHT7gQTFbWdq45MfwIrzbu_lyaupdhr --recipient EAa46iafkH0lpUkn7YGZ3kdvC9nNUiImhLNlODiw86AI --data @${KASSH_SCRIPT_DIR}/ecr-data.json +sleep 2 +kli vc list --name holder --alias holder --poll --verbose + +echo 'kli oobi resolve --name holder --oobi-alias kassh --oobi http://127.0.0.1:9723/oobi' diff --git a/scripts/auth-scripts.sh b/scripts/env.sh similarity index 100% rename from scripts/auth-scripts.sh rename to scripts/env.sh diff --git a/scripts/kassh.sh b/scripts/kassh.sh index 0a0617f..68fa4a5 100755 --- a/scripts/kassh.sh +++ b/scripts/kassh.sh @@ -3,6 +3,6 @@ kli init --name kassh --salt 0ACDEyMzQ1Njc4OWxtbm9dEf --nopasscode --config-dir ${KASSH_SCRIPT_DIR} --config-file demo-witness-oobis kli incept --name kassh --alias kassh --file ${KASSH_SCRIPT_DIR}/incept.json -kli oobi resolve --name kassh --oobi-alias schema --oobi http://10.254.41.113:7723/oobi/EKgMCHV98k4xz2rJnt2x556pGBCUfA6n5x03mvQv5tPo +kli oobi resolve --name kassh --oobi-alias schema --oobi http://192.168.86.232:7723/oobi/EM_FCDJGw6etiKHT7gQTFbWdq45MfwIrzbu_lyaupdhr kassh server start --name kassh --alias kassh diff --git a/scripts/keri/cf/demo-witness-oobis.json b/scripts/keri/cf/demo-witness-oobis.json index 86926d9..8da0e21 100755 --- a/scripts/keri/cf/demo-witness-oobis.json +++ b/scripts/keri/cf/demo-witness-oobis.json @@ -1,8 +1,8 @@ { "dt": "2022-01-20T12:57:59.823350+00:00", "iurls": [ - "http://10.254.41.113:5642/oobi/BBilc4-L3tFUnfM_wJr4S4OJanAv_VmF_dJNN6vkf2Ha/controller", - "http://10.254.41.113:5643/oobi/BLskRTInXnMxWaGqcpSyMgo0nYbalW99cGZESrz3zapM/controller", - "http://10.254.41.113:5644/oobi/BIKKuvBwpmDVA4Ds-EpL5bt9OqPzWPja2LigFYZN2YfX/controller" + "http://192.168.86.232:5642/oobi/BBilc4-L3tFUnfM_wJr4S4OJanAv_VmF_dJNN6vkf2Ha/controller", + "http://192.168.86.232:5643/oobi/BLskRTInXnMxWaGqcpSyMgo0nYbalW99cGZESrz3zapM/controller", + "http://192.168.86.232:5644/oobi/BIKKuvBwpmDVA4Ds-EpL5bt9OqPzWPja2LigFYZN2YfX/controller" ] } \ No newline at end of file diff --git a/scripts/keri/cf/main/wan.json b/scripts/keri/cf/main/wan.json index e69de29..b230bc4 100755 --- a/scripts/keri/cf/main/wan.json +++ b/scripts/keri/cf/main/wan.json @@ -0,0 +1,9 @@ +{ + "dt": "2022-01-20T12:57:59.823350+00:00", + "wan": { + "dt": "2022-01-20T12:57:59.823350+00:00", + "curls": ["tcp://192.168.86.232:5632/", "http://192.168.86.232:5642/"] + }, + "iurls": [ + ] +} diff --git a/scripts/keri/cf/main/wes.json b/scripts/keri/cf/main/wes.json index e69de29..fe45056 100755 --- a/scripts/keri/cf/main/wes.json +++ b/scripts/keri/cf/main/wes.json @@ -0,0 +1,9 @@ +{ + "wes": { + "dt": "2022-01-20T12:57:59.823350+00:00", + "curls": ["tcp://192.168.86.232:5634/", "http://192.168.86.232:5644/"] + }, + "dt": "2022-01-20T12:57:59.823350+00:00", + "iurls": [ + ] +} diff --git a/scripts/keri/cf/main/wil.json b/scripts/keri/cf/main/wil.json index e69de29..526a733 100755 --- a/scripts/keri/cf/main/wil.json +++ b/scripts/keri/cf/main/wil.json @@ -0,0 +1,9 @@ +{ + "wil": { + "dt": "2022-01-20T12:57:59.823350+00:00", + "curls": ["tcp://192.168.86.232:5633/", "http://192.168.86.232:5643/"] + }, + "dt": "2022-01-20T12:57:59.823350+00:00", + "iurls": [ + ] +} diff --git a/scripts/keri/cf/main/wit.json b/scripts/keri/cf/main/wit.json index e69de29..aba218b 100755 --- a/scripts/keri/cf/main/wit.json +++ b/scripts/keri/cf/main/wit.json @@ -0,0 +1,9 @@ +{ + "wit": { + "dt": "2022-01-20T12:57:59.823350+00:00", + "curls": ["tcp://127.0.0.1:5635/", "http://127.0.0.1:5645/"] + }, + "dt": "2022-01-20T12:57:59.823350+00:00", + "iurls": [ + ] +} diff --git a/scripts/keri/cf/main/wub.json b/scripts/keri/cf/main/wub.json index e69de29..fe06c95 100755 --- a/scripts/keri/cf/main/wub.json +++ b/scripts/keri/cf/main/wub.json @@ -0,0 +1,9 @@ +{ + "wub": { + "dt": "2022-01-20T12:57:59.823350+00:00", + "curls": ["tcp://127.0.0.1:5636/", "http://127.0.0.1:5646/"] + }, + "dt": "2022-01-20T12:57:59.823350+00:00", + "iurls": [ + ] +} diff --git a/scripts/keri/cf/main/wyz.json b/scripts/keri/cf/main/wyz.json index e69de29..350a9e6 100755 --- a/scripts/keri/cf/main/wyz.json +++ b/scripts/keri/cf/main/wyz.json @@ -0,0 +1,9 @@ +{ + "wyz": { + "dt": "2022-01-20T12:57:59.823350+00:00", + "curls": ["tcp://127.0.0.1:5637/", "http://127.0.0.1:5647/"] + }, + "dt": "2022-01-20T12:57:59.823350+00:00", + "iurls": [ + ] +} diff --git a/src/kassh/core/handling.py b/src/kassh/core/handling.py index 47d6f3f..b12aa58 100644 --- a/src/kassh/core/handling.py +++ b/src/kassh/core/handling.py @@ -19,8 +19,18 @@ from keri.core import coring from keri.help import helping -AUTH_SCHEMA_SAID = "EKgMCHV98k4xz2rJnt2x556pGBCUfA6n5x03mvQv5tPo" +class Schema: + AUTH_SCHEMA_SAID = "EKgMCHV98k4xz2rJnt2x556pGBCUfA6n5x03mvQv5tPo" + ECR_SCHEMA_SAID = "EM_FCDJGw6etiKHT7gQTFbWdq45MfwIrzbu_lyaupdhr" + + +EBA_DOCUMENT_SUBMITTER_ROLE = "EBA Document Submitter" + + +Banks = dict( + O2RNE8IBXP4R0TD8PU41="SOCIETE_GENERALE" +) def loadHandlers(hby, cdb, exc): """ Load handlers for the peer-to-peer challenge response protocol @@ -151,43 +161,99 @@ def processPresentations(self): if self.reger.saved.get(keys=(said,)) is not None: self.cdb.iss.rem(keys=(said,)) creder = self.reger.creds.get(keys=(said,)) - if creder.schema != AUTH_SCHEMA_SAID: - print(f"invalid credential presentation, schema {creder.schema} does not match {AUTH_SCHEMA_SAID}") - - kever = self.hby.kevers[creder.subject["i"]] - - user = creder.subject["userName"] - homeDir = os.path.join("/home", user) - if os.path.exists(homeDir): - print(f"not creating user, {user} already exists.") - - cmd = f"useradd -p xxx -m {user}" - if (err := os.system(cmd)) != 0: - print(f"unable to create user: {err}.") - - try: - ssh = os.path.join(homeDir, ".ssh") - os.mkdir(ssh) - authKeys = os.path.join(ssh, "authorized_keys") - f = open(authKeys, "w") - verkey = ed25519.Ed25519PublicKey.from_public_bytes(kever.verfers[0].raw) - pem = verkey.public_bytes(encoding=serialization.Encoding.OpenSSH, - format=serialization.PublicFormat.OpenSSH) - - for line in pem.splitlines(keepends=True): - f.write(line.decode("utf-8")) - - f.close() - uid, gid = pwd.getpwnam(user).pw_uid, pwd.getpwnam(user).pw_gid - os.chown(ssh, uid, gid) - os.chown(authKeys, uid, gid) - os.chmod(ssh, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR) - os.chmod(authKeys, stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH) - - self.cdb.accts.pin(keys=(creder.said,), val=(kever.prefixer, kever.sner)) - - except (FileExistsError, FileNotFoundError) as e: - print(f"error creating SSH directory and files: {e}") + match creder.schema: + case Schema.AUTH_SCHEMA_SAID: + self.processAuth(creder) + case Schema.ECR_SCHEMA_SAID: + self.processEcr(creder) + case _: + print(f"invalid credential presentation, schema {creder.schema}") + + def processEcr(self, creder): + kever = self.hby.kevers[creder.subject["i"]] + + role = creder.subject["engagementContextRole"] + if role != EBA_DOCUMENT_SUBMITTER_ROLE: + print(f"Invalid engagement context role {role}") + return + + user = creder.subject["LEI"] + + print(f"\tValid 'EBA Document Submitter' presented by {creder.subject['personLegalName']}") + + homeDir = os.path.join("/home", user) + if os.path.exists(homeDir): + print(f"not creating user, {user} already exists.") + else: + print(f"\tAccount {user} created.") + + cmd = f"useradd -p xxx -G sftp_users -m {user}" + if (err := os.system(cmd)) != 0: + print(f"unable to create user: {err}.") + + try: + ssh = os.path.join(homeDir, ".ssh") + os.mkdir(ssh) + authKeys = os.path.join(ssh, "authorized_keys") + f = open(authKeys, "w") + verkey = ed25519.Ed25519PublicKey.from_public_bytes(kever.verfers[0].raw) + pem = verkey.public_bytes(encoding=serialization.Encoding.OpenSSH, + format=serialization.PublicFormat.OpenSSH) + + for line in pem.splitlines(keepends=True): + f.write(line.decode("utf-8")) + + f.close() + + print(f"\t{creder.subject['personLegalName']} granted upload access") + + uid, gid = pwd.getpwnam(user).pw_uid, pwd.getpwnam(user).pw_gid + os.chown(ssh, uid, gid) + os.chown(authKeys, uid, gid) + os.chmod(ssh, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR) + os.chmod(authKeys, stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH) + + self.cdb.accts.pin(keys=(creder.said,), val=(kever.prefixer, kever.sner)) + + except (FileExistsError, FileNotFoundError) as e: + print(f"error creating SSH directory and files: {e}") + print() + + def processAuth(self, creder): + kever = self.hby.kevers[creder.subject["i"]] + + user = creder.subject["userName"] + homeDir = os.path.join("/home", user) + if os.path.exists(homeDir): + print(f"not creating user, {user} already exists.") + + cmd = f"useradd -p xxx -m {user}" + if (err := os.system(cmd)) != 0: + print(f"unable to create user: {err}.") + + try: + ssh = os.path.join(homeDir, ".ssh") + os.mkdir(ssh) + authKeys = os.path.join(ssh, "authorized_keys") + f = open(authKeys, "w") + verkey = ed25519.Ed25519PublicKey.from_public_bytes(kever.verfers[0].raw) + pem = verkey.public_bytes(encoding=serialization.Encoding.OpenSSH, + format=serialization.PublicFormat.OpenSSH) + + for line in pem.splitlines(keepends=True): + f.write(line.decode("utf-8")) + + f.close() + uid, gid = pwd.getpwnam(user).pw_uid, pwd.getpwnam(user).pw_gid + os.chown(ssh, uid, gid) + os.chown(authKeys, uid, gid) + os.chmod(ssh, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR) + os.chmod(authKeys, stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH) + + self.cdb.accts.pin(keys=(creder.said,), val=(kever.prefixer, kever.sner)) + + except (FileExistsError, FileNotFoundError) as e: + print(f"error creating SSH directory and files: {e}") def processRevocations(self): @@ -265,9 +331,16 @@ def monitorDo(self, tymth, tock=1.0): kever = self.hby.kevers[prefixer.qb64] if kever.sner.num > seqner.num: - print("Processing rotation...") + print("Identifier rotation detected") creder = self.reger.creds.get(keys=(said,)) - user = creder.subject["userName"] + match creder.schema: + case Schema.AUTH_SCHEMA_SAID: + user = creder.subject["userName"] + case Schema.ECR_SCHEMA_SAID: + user = creder.subject["LEI"] + case _: + continue + authKeys = os.path.join("/home", user, ".ssh", "authorized_keys") f = open(authKeys, "w") verkey = ed25519.Ed25519PublicKey.from_public_bytes(kever.verfers[0].raw) @@ -278,7 +351,8 @@ def monitorDo(self, tymth, tock=1.0): f.write(line.decode("utf-8")) f.close() - print(f"new key written to {authKeys}") + print(f"\tAccess credentials for {creder.subject['personLegalName']} updated.") + print() self.cdb.accts.pin(keys=(creder.said,), val=(kever.prefixer, kever.sner)) yield 1.0