From c66be829b40e6ee973ab6bbba6144fa913bfa211 Mon Sep 17 00:00:00 2001 From: Vivien Kraus Date: Sat, 5 Dec 2020 13:11:37 +0100 Subject: Implement an identity provider --- po/POTFILES.in | 1 + po/fr.po | 532 ++++++++++++++++++------------- po/webid-oidc.pot | 168 +++++++++- src/scm/webid-oidc/ChangeLog | 3 + src/scm/webid-oidc/Makefile.am | 6 +- src/scm/webid-oidc/identity-provider.scm | 355 +++++++++++++++++++++ 6 files changed, 841 insertions(+), 224 deletions(-) create mode 100644 src/scm/webid-oidc/identity-provider.scm diff --git a/po/POTFILES.in b/po/POTFILES.in index 6ffff1e..ed66784 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -7,4 +7,5 @@ src/jwk/libwebidoidc-jwk.c src/jwk/generate-key.c src/hash/libwebidoidc-hash.c src/scm/webid-oidc/errors.scm +src/scm/webid-oidc/identity-provider.scm src/scm/webid-oidc/authorization-page-unsafe.scm diff --git a/po/fr.po b/po/fr.po index ed6fea5..4713516 100644 --- a/po/fr.po +++ b/po/fr.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: webid-oidc 0.0.0\n" "Report-Msgid-Bugs-To: vivien@planete-kraus.eu\n" -"POT-Creation-Date: 2021-06-05 16:16+0200\n" +"POT-Creation-Date: 2021-06-05 16:17+0200\n" "PO-Revision-Date: 2021-06-05 11:07+0200\n" "Last-Translator: Vivien Kraus \n" "Language-Team: French \n" @@ -697,6 +697,316 @@ msgstr "il y a une erreur" msgid "Unhandled exception type ~a." msgstr "Type d’exception non pris en charge ~a." +#: src/scm/webid-oidc/identity-provider.scm:54 +msgid "Warning: generating a new key pair." +msgstr "Attention : génération d'une nouvelle paire de clé." + +#: src/scm/webid-oidc/identity-provider.scm:148 +msgid "command-line|version" +msgstr "version" + +#: src/scm/webid-oidc/identity-provider.scm:150 +msgid "comand-line|help" +msgstr "aide" + +#: src/scm/webid-oidc/identity-provider.scm:152 +msgid "comand-line|issuer" +msgstr "émetteur" + +#: src/scm/webid-oidc/identity-provider.scm:154 +msgid "comand-line|key-file" +msgstr "fichier-clé" + +#: src/scm/webid-oidc/identity-provider.scm:156 +msgid "comand-line|subject" +msgstr "sujet" + +#: src/scm/webid-oidc/identity-provider.scm:158 +msgid "comand-line|password" +msgstr "mot-de-passe" + +#: src/scm/webid-oidc/identity-provider.scm:160 +msgid "comand-line|jwks-uri" +msgstr "uri-jwks" + +#: src/scm/webid-oidc/identity-provider.scm:162 +msgid "comand-line|authorization-endpoint-uri" +msgstr "uri-terminal-autorisation" + +#: src/scm/webid-oidc/identity-provider.scm:164 +msgid "comand-line|token-endpoint-uri" +msgstr "uri-terminal-jeton" + +#: src/scm/webid-oidc/identity-provider.scm:166 +msgid "comand-line|port" +msgstr "port" + +#: src/scm/webid-oidc/identity-provider.scm:168 +msgid "comand-line|log-file" +msgstr "fichier-journal" + +#: src/scm/webid-oidc/identity-provider.scm:170 +msgid "comand-line|error-file" +msgstr "fichier-erreur" + +#: src/scm/webid-oidc/identity-provider.scm:188 +#, fuzzy, scheme-format +#| msgid "" +#| "Usage: ~a [OPTIONS]...\n" +#| "\n" +#| "Run the Solid identity provider for a specific user.\n" +#| "\n" +#| "Options:\n" +#| " -h, --~a:\n" +#| " display this help message and exit.\n" +#| " -v, --~a:\n" +#| " display the version information (~a) and exit.\n" +#| " -i URI, --~a=URI:\n" +#| " set the public server host name.\n" +#| " -k FILE, --~a=FILE.jwk:\n" +#| " set the file name of the key file. If it does not exist, a new\n" +#| " key is generated.\n" +#| " -s WEBID, --~a=WEBID:\n" +#| " set the identity of the subject.\n" +#| " -w PASSWORD, --~a=PASSWORD:\n" +#| " set the password to recognize the user.\n" +#| " -j URI, --~a=URI:\n" +#| " set the URI to query the key of the server.\n" +#| " -a URI, --~a=URI:\n" +#| " set the authorization endpoint of the issuer.\n" +#| " -t URI, --~a=URI:\n" +#| " set the token endpoint of the issuer.\n" +#| " -p PORT, --~a=PORT:\n" +#| " set the port to bind (instead of 8080).\n" +#| " -l FILE.log, --~a=FILE.log:\n" +#| " dump the standard output to that file.\n" +#| " -e FILE.err, --~a=FILE.err:\n" +#| " dump the standard error to that file.\n" +#| "\n" +#| "Environment variables:\n" +#| "\n" +#| " LANG: set the locale of the sysadmin-facing interface (the user\n" +#| "pages are translated according to the user agent’s Accept-language\n" +#| "header), for log files and command-line interface. It is currently ~a.\n" +#| "\n" +#| " XDG_DATA_HOME: where to store the refresh tokens (under the\n" +#| "webid-oidc directory). For a system service, it is recommended to set\n" +#| "it to /var/lib. Currently set to ~a.\n" +#| "\n" +#| " XDG_CACHE_HOME: where to store and update the seed file for the\n" +#| "random number generator. If you remove it, you need to restart the\n" +#| "program to use a different seed. Currently set to ~a.\n" +#| "\n" +#| " HOME: if XDG_DATA_HOME or XDG_CACHE_HOME is not set, they are\n" +#| "computed from the value of the HOME environment variable. It is not\n" +#| "used otherwise. Currently set to ~a.\n" +#| "\n" +#| "Example used in webid-oidc-demo.planete-kraus.eu (except it’s managed\n" +#| "by shepherd in reality):\n" +#| "\n" +#| " export LANG=C\n" +#| " export XDG_DATA_HOME=/var/lib\n" +#| " export XDG_CACHE_HOME=/var/cache\n" +#| " webid-oidc-issuer \\\n" +#| " --issuer https://webid-oidc-demo.planete-kraus.eu \\\n" +#| " --key-file /var/lib/webid-oidc/issuer/key.jwk \\\n" +#| " --subject https://webid-oidc-demo.planete-kraus.eu/profile/card#me " +#| "\\\n" +#| " --password \"$PASSWORD\" \\\n" +#| " --jwks-uri https://webid-oidc-demo.planete-kraus.eu/keys \\\n" +#| " --authorization-endpoint-uri https://webid-oidc-demo.planete-kraus." +#| "eu/authorize \\\n" +#| " --token-endpoint-uri https://webid-oidc-demo.planete-kraus.eu/token " +#| "\\\n" +#| " --port $PORT\n" +#| "\n" +#| "If you find a bug, send a report to ~a.\n" +msgid "" +"Usage: ~a [OPTIONS]...\n" +"\n" +"Run the Solid identity provider for a specific user.\n" +"\n" +"Options:\n" +" -h, --~a:\n" +" display this help message and exit.\n" +" -v, --~a:\n" +" display the version information (~a) and exit.\n" +" -i URI, --~a=URI:\n" +" set the public server host name.\n" +" -k FILE, --~a=FILE.jwk:\n" +" set the file name of the key file. If it does not exist, a new\n" +" key is generated.\n" +" -s WEBID, --~a=WEBID:\n" +" set the identity of the subject.\n" +" -w PASSWORD, --~a=PASSWORD:\n" +" set the password to recognize the user.\n" +" -j URI, --~a=URI:\n" +" set the URI to query the key of the server.\n" +" -a URI, --~a=URI:\n" +" set the authorization endpoint of the issuer.\n" +" -t URI, --~a=URI:\n" +" set the token endpoint of the issuer.\n" +" -p PORT, --~a=PORT:\n" +" set the port to bind (instead of 8080).\n" +" -l FILE.log, --~a=FILE.log:\n" +" dump the standard output to that file.\n" +" -e FILE.err, --~a=FILE.err:\n" +" dump the standard error to that file.\n" +"\n" +"Environment variables:\n" +"\n" +" LANG: set the locale of the sysadmin-facing interface (the user\n" +"pages are translated according to the user agent’s Accept-language\n" +"header), for log files and command-line interface. It is currently ~a.\n" +"\n" +" XDG_DATA_HOME: where to store the refresh tokens (under the\n" +"webid-oidc directory). For a system service, it is recommended to set\n" +"it to /var/lib. Currently set to ~a.\n" +"\n" +" XDG_CACHE_HOME: where to store and update the seed file for the\n" +"random number generator. If you remove it, you need to restart the\n" +"program to use a different seed. Currently set to ~a.\n" +"\n" +" HOME: if XDG_DATA_HOME or XDG_CACHE_HOME is not set, they are\n" +"computed from the value of the HOME environment variable. It is not\n" +"used otherwise. Currently set to ~a.\n" +"\n" +"Example used in webid-oidc-demo.planete-kraus.eu (except it’s managed\n" +"by shepherd in reality):\n" +"\n" +" export LANG=C\n" +" export XDG_DATA_HOME=/var/lib\n" +" export XDG_CACHE_HOME=/var/cache\n" +" webid-oidc-issuer \\\n" +" --issuer https://webid-oidc-demo.planete-kraus.eu \\\n" +" --key-file /var/lib/webid-oidc/issuer/key.jwk \\\n" +" --subject https://webid-oidc-demo.planete-kraus.eu/profile/card#me \\\n" +" --password \"$PASSWORD\" \\\n" +" --jwks-uri https://webid-oidc-demo.planete-kraus.eu/keys \\\n" +" --authorization-endpoint https://webid-oidc-demo.planete-kraus.eu/" +"authorize \\\n" +" --token-endpoint https://webid-oidc-demo.planete-kraus.eu/token \\\n" +" --port $PORT\n" +"\n" +"If you find a bug, send a report to ~a.\n" +msgstr "" +"Utilisation : ~a [OPTIONS]...\n" +"\n" +"Exécute le fournisseur d’identité Solid pour un utilisateur spécifique.\n" +"\n" +"Options :\n" +" -h, --~a :\n" +" affiche ce message d’aide et quitte.\n" +" -v, --~a :\n" +" affiche le numéro de version (~a) et quitte.\n" +" -i URI, --~a=URI :\n" +" définit le nom public du serveur.\n" +" -k FICHIER, --~a=FICHIER.jwk :\n" +" définit le nom du fichier de clé. S’il n’existe pas, une\n" +" nouvelle clé sera générée.\n" +" -s WEBID, --~a=WEBID :\n" +" définit l’identité du sujet.\n" +" -w MOTDEPASSE, --~a=MOTDEPASSE :\n" +" définit le mot de passe pour reconnaître l’utilisateur.\n" +" -j URI, --~a=URI :\n" +" définit l’URI pour obtenir la clé publique du serveur.\n" +" -a URI, --~a=URI :\n" +" définit le terminal d’autorisation de l’émetteur (authorization\n" +" endpoint).\n" +" -t URI, --~a=URI :\n" +" définit le terminal de jeton de l’émetteur (token endpoint).\n" +" -p PORT, --~a=PORT :\n" +" définit le port à lier (au lieu de 8080).\n" +" -l FICHIER.log, --~a=FICHIER.log :\n" +" déverser la sortie standard vers ce fichier.\n" +" -e FICHIER.err, --~a=FICHIER.err :\n" +" déverser la sortie d’erreur vers ce fichier.\n" +"\n" +"Variables d’environnement :\n" +"\n" +" LANG : définit la locale de l’interface de l’administrateur système\n" +"(les pages utilisateur sont traduites selon l’en-tête Accept-Language\n" +"de l’agent), pour les fichiers de journaux et l’interface en ligne de\n" +"commande. Elle vaut actuellement ~a.\n" +"\n" +" XDG_DATA_HOME : où stocker les jetons de rafraîchissement (refresh\n" +"tokens, dans un sous-dossier webid-oidc). Pour un service système, il\n" +"est recommandé d’affecter /var/lib. Actuellement définie à ~a.\n" +"\n" +" XDG_CACHE_HOME : où stocker et modifier le fichier de graine pour le\n" +"générateur de nombres aléatoires. Si vous le supprimez, vous devez\n" +"redémarrer le programme pour utiliser une graine\n" +"différente. Actuellement définie à ~a.\n" +"\n" +" HOME : si XDG_DATA_HOME ou XDG_CACHE_HOME ne sont pas définies,\n" +"elles sont calculées à partir de la valeur de la variable\n" +"d’environnement HOME. Elle n’est pas utilisée dans les autres\n" +"cas. Actuellement définie à ~a.\n" +"\n" +"Exemple utilisé pour webid-oidc-demo.planete-kraus.eu (sauf que le\n" +"service est géré par shepherd en réalité, et les URI sont en\n" +"anglais) :\n" +"\n" +" export LANG=fr_FR.UTF-8\n" +" export XDG_DATA_HOME=/var/lib\n" +" export XDG_CACHE_HOME=/var/cache\n" +" webid-oidc-issuer \\\n" +" --émetteur https://webid-oidc-demo.planete-kraus.eu \\\n" +" --fichier-clé /var/lib/webid-oidc/émetteur/clé.jwk \\\n" +" --sujet https://webid-oidc-demo.planete-kraus.eu/profil/carte#moi \\\n" +" --mot-de-passe \"$MOTDEPASSE\" \\\n" +" --uri-jwks https://webid-oidc-demo.planete-kraus.eu/clés \\\n" +" --uri-terminal-autorisation https://webid-oidc-demo.planete-kraus.eu/" +"autoriser \\\n" +" --uri-terminal-jeton https://webid-oidc-demo.planete-kraus.eu/jeton " +"\\\n" +" --port $PORT\n" +"\n" +"Si vous trouvez une erreur dans le programme, envoyez-en un rapport à ~a.\n" + +#: src/scm/webid-oidc/identity-provider.scm:267 +#, scheme-format +msgid "~a version ~a\n" +msgstr "~a version ~a\n" + +#: src/scm/webid-oidc/identity-provider.scm:294 +msgid "You need to set the issuer.\n" +msgstr "Vous devez définir l'émetteur.\n" + +#: src/scm/webid-oidc/identity-provider.scm:298 +msgid "You need to set the file name of the key file.\n" +msgstr "Vous devez définir le nom de ficher du fichier de clé.\n" + +#: src/scm/webid-oidc/identity-provider.scm:302 +msgid "You need to set the identity of the subject.\n" +msgstr "Vous devez définir l'identité du sujet.\n" + +#: src/scm/webid-oidc/identity-provider.scm:306 +msgid "You need to set the password to verify the identity of the subject.\n" +msgstr "Vous devez définir le mot de passe pour identifier le sujet.\n" + +#: src/scm/webid-oidc/identity-provider.scm:310 +msgid "You need to set the JWKS URI.\n" +msgstr "Vous devez définir l'URI du JWKS.\n" + +#: src/scm/webid-oidc/identity-provider.scm:315 +msgid "You need to set the authorization endpoint URI.\n" +msgstr "Vous devez définir l'URI du terminal d'autorisation.\n" + +#: src/scm/webid-oidc/identity-provider.scm:320 +msgid "You need to set the token endpoint URI.\n" +msgstr "Vous devez définir l'URI du terminal de jeton.\n" + +#: src/scm/webid-oidc/identity-provider.scm:327 +msgid "The port should be a number between 0 and 65535.\n" +msgstr "Le port doit être un nombre entre 0 et 65535.\n" + +#: src/scm/webid-oidc/identity-provider.scm:346 +#, fuzzy, scheme-format +#| msgid "~a: Internal server error: ~a\n" +msgid "Internal server error: ~a\n" +msgstr "~a : Erreur interne du serveur : ~a\n" + #: src/scm/webid-oidc/authorization-page-unsafe.scm:29 msgid "xml-lang|en" msgstr "fr" @@ -922,226 +1232,6 @@ msgstr "" #~ msgid "there is an external error" #~ msgstr "il y a une erreur externe" -#~ msgid "Warning: generating a new key pair." -#~ msgstr "Attention : génération d'une nouvelle paire de clé." - -#~ msgid "command-line|version" -#~ msgstr "version" - -#~ msgid "comand-line|help" -#~ msgstr "aide" - -#~ msgid "comand-line|issuer" -#~ msgstr "émetteur" - -#~ msgid "comand-line|key-file" -#~ msgstr "fichier-clé" - -#~ msgid "comand-line|subject" -#~ msgstr "sujet" - -#~ msgid "comand-line|password" -#~ msgstr "mot-de-passe" - -#~ msgid "comand-line|jwks-uri" -#~ msgstr "uri-jwks" - -#~ msgid "comand-line|authorization-endpoint-uri" -#~ msgstr "uri-terminal-autorisation" - -#~ msgid "comand-line|token-endpoint-uri" -#~ msgstr "uri-terminal-jeton" - -#~ msgid "comand-line|port" -#~ msgstr "port" - -#~ msgid "comand-line|log-file" -#~ msgstr "fichier-journal" - -#~ msgid "comand-line|error-file" -#~ msgstr "fichier-erreur" - -#, scheme-format -#~ msgid "" -#~ "Usage: ~a [OPTIONS]...\n" -#~ "\n" -#~ "Run the Solid identity provider for a specific user.\n" -#~ "\n" -#~ "Options:\n" -#~ " -h, --~a:\n" -#~ " display this help message and exit.\n" -#~ " -v, --~a:\n" -#~ " display the version information (~a) and exit.\n" -#~ " -i URI, --~a=URI:\n" -#~ " set the public server host name.\n" -#~ " -k FILE, --~a=FILE.jwk:\n" -#~ " set the file name of the key file. If it does not exist, a new\n" -#~ " key is generated.\n" -#~ " -s WEBID, --~a=WEBID:\n" -#~ " set the identity of the subject.\n" -#~ " -w PASSWORD, --~a=PASSWORD:\n" -#~ " set the password to recognize the user.\n" -#~ " -j URI, --~a=URI:\n" -#~ " set the URI to query the key of the server.\n" -#~ " -a URI, --~a=URI:\n" -#~ " set the authorization endpoint of the issuer.\n" -#~ " -t URI, --~a=URI:\n" -#~ " set the token endpoint of the issuer.\n" -#~ " -p PORT, --~a=PORT:\n" -#~ " set the port to bind (instead of 8080).\n" -#~ " -l FILE.log, --~a=FILE.log:\n" -#~ " dump the standard output to that file.\n" -#~ " -e FILE.err, --~a=FILE.err:\n" -#~ " dump the standard error to that file.\n" -#~ "\n" -#~ "Environment variables:\n" -#~ "\n" -#~ " LANG: set the locale of the sysadmin-facing interface (the user\n" -#~ "pages are translated according to the user agent’s Accept-language\n" -#~ "header), for log files and command-line interface. It is currently ~a.\n" -#~ "\n" -#~ " XDG_DATA_HOME: where to store the refresh tokens (under the\n" -#~ "webid-oidc directory). For a system service, it is recommended to set\n" -#~ "it to /var/lib. Currently set to ~a.\n" -#~ "\n" -#~ " XDG_CACHE_HOME: where to store and update the seed file for the\n" -#~ "random number generator. If you remove it, you need to restart the\n" -#~ "program to use a different seed. Currently set to ~a.\n" -#~ "\n" -#~ " HOME: if XDG_DATA_HOME or XDG_CACHE_HOME is not set, they are\n" -#~ "computed from the value of the HOME environment variable. It is not\n" -#~ "used otherwise. Currently set to ~a.\n" -#~ "\n" -#~ "Example used in webid-oidc-demo.planete-kraus.eu (except it’s managed\n" -#~ "by shepherd in reality):\n" -#~ "\n" -#~ " export LANG=C\n" -#~ " export XDG_DATA_HOME=/var/lib\n" -#~ " export XDG_CACHE_HOME=/var/cache\n" -#~ " webid-oidc-issuer \\\n" -#~ " --issuer https://webid-oidc-demo.planete-kraus.eu \\\n" -#~ " --key-file /var/lib/webid-oidc/issuer/key.jwk \\\n" -#~ " --subject https://webid-oidc-demo.planete-kraus.eu/profile/card#me " -#~ "\\\n" -#~ " --password \"$PASSWORD\" \\\n" -#~ " --jwks-uri https://webid-oidc-demo.planete-kraus.eu/keys \\\n" -#~ " --authorization-endpoint-uri https://webid-oidc-demo.planete-kraus." -#~ "eu/authorize \\\n" -#~ " --token-endpoint-uri https://webid-oidc-demo.planete-kraus.eu/token " -#~ "\\\n" -#~ " --port $PORT\n" -#~ "\n" -#~ "If you find a bug, send a report to ~a.\n" -#~ msgstr "" -#~ "Utilisation : ~a [OPTIONS]...\n" -#~ "\n" -#~ "Exécute le fournisseur d’identité Solid pour un utilisateur spécifique.\n" -#~ "\n" -#~ "Options :\n" -#~ " -h, --~a :\n" -#~ " affiche ce message d’aide et quitte.\n" -#~ " -v, --~a :\n" -#~ " affiche le numéro de version (~a) et quitte.\n" -#~ " -i URI, --~a=URI :\n" -#~ " définit le nom public du serveur.\n" -#~ " -k FICHIER, --~a=FICHIER.jwk :\n" -#~ " définit le nom du fichier de clé. S’il n’existe pas, une\n" -#~ " nouvelle clé sera générée.\n" -#~ " -s WEBID, --~a=WEBID :\n" -#~ " définit l’identité du sujet.\n" -#~ " -w MOTDEPASSE, --~a=MOTDEPASSE :\n" -#~ " définit le mot de passe pour reconnaître l’utilisateur.\n" -#~ " -j URI, --~a=URI :\n" -#~ " définit l’URI pour obtenir la clé publique du serveur.\n" -#~ " -a URI, --~a=URI :\n" -#~ " définit le terminal d’autorisation de l’émetteur (authorization\n" -#~ " endpoint).\n" -#~ " -t URI, --~a=URI :\n" -#~ " définit le terminal de jeton de l’émetteur (token endpoint).\n" -#~ " -p PORT, --~a=PORT :\n" -#~ " définit le port à lier (au lieu de 8080).\n" -#~ " -l FICHIER.log, --~a=FICHIER.log :\n" -#~ " déverser la sortie standard vers ce fichier.\n" -#~ " -e FICHIER.err, --~a=FICHIER.err :\n" -#~ " déverser la sortie d’erreur vers ce fichier.\n" -#~ "\n" -#~ "Variables d’environnement :\n" -#~ "\n" -#~ " LANG : définit la locale de l’interface de l’administrateur système\n" -#~ "(les pages utilisateur sont traduites selon l’en-tête Accept-Language\n" -#~ "de l’agent), pour les fichiers de journaux et l’interface en ligne de\n" -#~ "commande. Elle vaut actuellement ~a.\n" -#~ "\n" -#~ " XDG_DATA_HOME : où stocker les jetons de rafraîchissement (refresh\n" -#~ "tokens, dans un sous-dossier webid-oidc). Pour un service système, il\n" -#~ "est recommandé d’affecter /var/lib. Actuellement définie à ~a.\n" -#~ "\n" -#~ " XDG_CACHE_HOME : où stocker et modifier le fichier de graine pour le\n" -#~ "générateur de nombres aléatoires. Si vous le supprimez, vous devez\n" -#~ "redémarrer le programme pour utiliser une graine\n" -#~ "différente. Actuellement définie à ~a.\n" -#~ "\n" -#~ " HOME : si XDG_DATA_HOME ou XDG_CACHE_HOME ne sont pas définies,\n" -#~ "elles sont calculées à partir de la valeur de la variable\n" -#~ "d’environnement HOME. Elle n’est pas utilisée dans les autres\n" -#~ "cas. Actuellement définie à ~a.\n" -#~ "\n" -#~ "Exemple utilisé pour webid-oidc-demo.planete-kraus.eu (sauf que le\n" -#~ "service est géré par shepherd en réalité, et les URI sont en\n" -#~ "anglais) :\n" -#~ "\n" -#~ " export LANG=fr_FR.UTF-8\n" -#~ " export XDG_DATA_HOME=/var/lib\n" -#~ " export XDG_CACHE_HOME=/var/cache\n" -#~ " webid-oidc-issuer \\\n" -#~ " --émetteur https://webid-oidc-demo.planete-kraus.eu \\\n" -#~ " --fichier-clé /var/lib/webid-oidc/émetteur/clé.jwk \\\n" -#~ " --sujet https://webid-oidc-demo.planete-kraus.eu/profil/carte#moi " -#~ "\\\n" -#~ " --mot-de-passe \"$MOTDEPASSE\" \\\n" -#~ " --uri-jwks https://webid-oidc-demo.planete-kraus.eu/clés \\\n" -#~ " --uri-terminal-autorisation https://webid-oidc-demo.planete-kraus." -#~ "eu/autoriser \\\n" -#~ " --uri-terminal-jeton https://webid-oidc-demo.planete-kraus.eu/jeton " -#~ "\\\n" -#~ " --port $PORT\n" -#~ "\n" -#~ "Si vous trouvez une erreur dans le programme, envoyez-en un rapport à " -#~ "~a.\n" - -#, scheme-format -#~ msgid "~a version ~a\n" -#~ msgstr "~a version ~a\n" - -#~ msgid "You need to set the issuer.\n" -#~ msgstr "Vous devez définir l'émetteur.\n" - -#~ msgid "You need to set the file name of the key file.\n" -#~ msgstr "Vous devez définir le nom de ficher du fichier de clé.\n" - -#~ msgid "You need to set the identity of the subject.\n" -#~ msgstr "Vous devez définir l'identité du sujet.\n" - -#~ msgid "" -#~ "You need to set the password to verify the identity of the subject.\n" -#~ msgstr "Vous devez définir le mot de passe pour identifier le sujet.\n" - -#~ msgid "You need to set the JWKS URI.\n" -#~ msgstr "Vous devez définir l'URI du JWKS.\n" - -#~ msgid "You need to set the authorization endpoint URI.\n" -#~ msgstr "Vous devez définir l'URI du terminal d'autorisation.\n" - -#~ msgid "You need to set the token endpoint URI.\n" -#~ msgstr "Vous devez définir l'URI du terminal de jeton.\n" - -#~ msgid "The port should be a number between 0 and 65535.\n" -#~ msgstr "Le port doit être un nombre entre 0 et 65535.\n" - -#, scheme-format -#~ msgid "~a: Internal server error: ~a\n" -#~ msgstr "~a : Erreur interne du serveur : ~a\n" - #, scheme-format #~ msgid "" #~ "The client locale ~s can’t be approximated by system locale ~s (because " diff --git a/po/webid-oidc.pot b/po/webid-oidc.pot index cf36502..1516073 100644 --- a/po/webid-oidc.pot +++ b/po/webid-oidc.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: webid-oidc SNAPSHOT\n" "Report-Msgid-Bugs-To: vivien@planete-kraus.eu\n" -"POT-Creation-Date: 2021-06-05 16:16+0200\n" +"POT-Creation-Date: 2021-06-05 16:17+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -680,6 +680,172 @@ msgstr "" msgid "Unhandled exception type ~a." msgstr "" +#: src/scm/webid-oidc/identity-provider.scm:54 +msgid "Warning: generating a new key pair." +msgstr "" + +#: src/scm/webid-oidc/identity-provider.scm:148 +msgid "command-line|version" +msgstr "" + +#: src/scm/webid-oidc/identity-provider.scm:150 +msgid "comand-line|help" +msgstr "" + +#: src/scm/webid-oidc/identity-provider.scm:152 +msgid "comand-line|issuer" +msgstr "" + +#: src/scm/webid-oidc/identity-provider.scm:154 +msgid "comand-line|key-file" +msgstr "" + +#: src/scm/webid-oidc/identity-provider.scm:156 +msgid "comand-line|subject" +msgstr "" + +#: src/scm/webid-oidc/identity-provider.scm:158 +msgid "comand-line|password" +msgstr "" + +#: src/scm/webid-oidc/identity-provider.scm:160 +msgid "comand-line|jwks-uri" +msgstr "" + +#: src/scm/webid-oidc/identity-provider.scm:162 +msgid "comand-line|authorization-endpoint-uri" +msgstr "" + +#: src/scm/webid-oidc/identity-provider.scm:164 +msgid "comand-line|token-endpoint-uri" +msgstr "" + +#: src/scm/webid-oidc/identity-provider.scm:166 +msgid "comand-line|port" +msgstr "" + +#: src/scm/webid-oidc/identity-provider.scm:168 +msgid "comand-line|log-file" +msgstr "" + +#: src/scm/webid-oidc/identity-provider.scm:170 +msgid "comand-line|error-file" +msgstr "" + +#: src/scm/webid-oidc/identity-provider.scm:188 +#, scheme-format +msgid "" +"Usage: ~a [OPTIONS]...\n" +"\n" +"Run the Solid identity provider for a specific user.\n" +"\n" +"Options:\n" +" -h, --~a:\n" +" display this help message and exit.\n" +" -v, --~a:\n" +" display the version information (~a) and exit.\n" +" -i URI, --~a=URI:\n" +" set the public server host name.\n" +" -k FILE, --~a=FILE.jwk:\n" +" set the file name of the key file. If it does not exist, a new\n" +" key is generated.\n" +" -s WEBID, --~a=WEBID:\n" +" set the identity of the subject.\n" +" -w PASSWORD, --~a=PASSWORD:\n" +" set the password to recognize the user.\n" +" -j URI, --~a=URI:\n" +" set the URI to query the key of the server.\n" +" -a URI, --~a=URI:\n" +" set the authorization endpoint of the issuer.\n" +" -t URI, --~a=URI:\n" +" set the token endpoint of the issuer.\n" +" -p PORT, --~a=PORT:\n" +" set the port to bind (instead of 8080).\n" +" -l FILE.log, --~a=FILE.log:\n" +" dump the standard output to that file.\n" +" -e FILE.err, --~a=FILE.err:\n" +" dump the standard error to that file.\n" +"\n" +"Environment variables:\n" +"\n" +" LANG: set the locale of the sysadmin-facing interface (the user\n" +"pages are translated according to the user agent’s Accept-language\n" +"header), for log files and command-line interface. It is currently ~a.\n" +"\n" +" XDG_DATA_HOME: where to store the refresh tokens (under the\n" +"webid-oidc directory). For a system service, it is recommended to set\n" +"it to /var/lib. Currently set to ~a.\n" +"\n" +" XDG_CACHE_HOME: where to store and update the seed file for the\n" +"random number generator. If you remove it, you need to restart the\n" +"program to use a different seed. Currently set to ~a.\n" +"\n" +" HOME: if XDG_DATA_HOME or XDG_CACHE_HOME is not set, they are\n" +"computed from the value of the HOME environment variable. It is not\n" +"used otherwise. Currently set to ~a.\n" +"\n" +"Example used in webid-oidc-demo.planete-kraus.eu (except it’s managed\n" +"by shepherd in reality):\n" +"\n" +" export LANG=C\n" +" export XDG_DATA_HOME=/var/lib\n" +" export XDG_CACHE_HOME=/var/cache\n" +" webid-oidc-issuer \\\n" +" --issuer https://webid-oidc-demo.planete-kraus.eu \\\n" +" --key-file /var/lib/webid-oidc/issuer/key.jwk \\\n" +" --subject https://webid-oidc-demo.planete-kraus.eu/profile/card#me \\\n" +" --password \"$PASSWORD\" \\\n" +" --jwks-uri https://webid-oidc-demo.planete-kraus.eu/keys \\\n" +" --authorization-endpoint https://webid-oidc-demo.planete-kraus.eu/" +"authorize \\\n" +" --token-endpoint https://webid-oidc-demo.planete-kraus.eu/token \\\n" +" --port $PORT\n" +"\n" +"If you find a bug, send a report to ~a.\n" +msgstr "" + +#: src/scm/webid-oidc/identity-provider.scm:267 +#, scheme-format +msgid "~a version ~a\n" +msgstr "" + +#: src/scm/webid-oidc/identity-provider.scm:294 +msgid "You need to set the issuer.\n" +msgstr "" + +#: src/scm/webid-oidc/identity-provider.scm:298 +msgid "You need to set the file name of the key file.\n" +msgstr "" + +#: src/scm/webid-oidc/identity-provider.scm:302 +msgid "You need to set the identity of the subject.\n" +msgstr "" + +#: src/scm/webid-oidc/identity-provider.scm:306 +msgid "You need to set the password to verify the identity of the subject.\n" +msgstr "" + +#: src/scm/webid-oidc/identity-provider.scm:310 +msgid "You need to set the JWKS URI.\n" +msgstr "" + +#: src/scm/webid-oidc/identity-provider.scm:315 +msgid "You need to set the authorization endpoint URI.\n" +msgstr "" + +#: src/scm/webid-oidc/identity-provider.scm:320 +msgid "You need to set the token endpoint URI.\n" +msgstr "" + +#: src/scm/webid-oidc/identity-provider.scm:327 +msgid "The port should be a number between 0 and 65535.\n" +msgstr "" + +#: src/scm/webid-oidc/identity-provider.scm:346 +#, scheme-format +msgid "Internal server error: ~a\n" +msgstr "" + #: src/scm/webid-oidc/authorization-page-unsafe.scm:29 msgid "xml-lang|en" msgstr "" diff --git a/src/scm/webid-oidc/ChangeLog b/src/scm/webid-oidc/ChangeLog index 8ce40eb..2f6025a 100644 --- a/src/scm/webid-oidc/ChangeLog +++ b/src/scm/webid-oidc/ChangeLog @@ -117,6 +117,9 @@ 2020-12-05 Vivien Kraus + * identity-provider.scm (make-identity-provider): Also serve a + dummy resource for the subject. + * dpop-proof.scm (dpop-proof-decode): Accept a predicate to decode a dpop proof, so that we can use it for the token endpoint. diff --git a/src/scm/webid-oidc/Makefile.am b/src/scm/webid-oidc/Makefile.am index 8436089..6676fe9 100644 --- a/src/scm/webid-oidc/Makefile.am +++ b/src/scm/webid-oidc/Makefile.am @@ -17,7 +17,8 @@ dist_webidoidcmod_DATA += \ %reldir%/authorization-page.scm \ %reldir%/authorization-page-unsafe.scm \ %reldir%/authorization-endpoint.scm \ - %reldir%/token-endpoint.scm + %reldir%/token-endpoint.scm \ + %reldir%/identity-provider.scm webidoidcgo_DATA += \ %reldir%/errors.go \ @@ -38,6 +39,7 @@ webidoidcgo_DATA += \ %reldir%/authorization-page.go \ %reldir%/authorization-page-unsafe.go \ %reldir%/authorization-endpoint.go \ - %reldir%/token-endpoint.go + %reldir%/token-endpoint.go \ + %reldir%/identity-provider.go EXTRA_DIST += %reldir%/ChangeLog diff --git a/src/scm/webid-oidc/identity-provider.scm b/src/scm/webid-oidc/identity-provider.scm new file mode 100644 index 0000000..de49fc5 --- /dev/null +++ b/src/scm/webid-oidc/identity-provider.scm @@ -0,0 +1,355 @@ +(define-module (webid-oidc identity-provider) + #:use-module (webid-oidc errors) + #:use-module (webid-oidc authorization-endpoint) + #:use-module (webid-oidc token-endpoint) + #:use-module (webid-oidc oidc-configuration) + #:use-module (webid-oidc jwk) + #:use-module ((webid-oidc config) #:prefix cfg:) + #:use-module ((webid-oidc stubs) #:prefix stubs:) + #:use-module (webid-oidc jti) + #:use-module (web request) + #:use-module (web response) + #:use-module (web uri) + #:use-module (web client) + #:use-module (web server) + #:use-module (webid-oidc cache) + #:use-module (ice-9 optargs) + #:use-module (ice-9 receive) + #:use-module (ice-9 i18n) + #:use-module (ice-9 getopt-long) + #:use-module (ice-9 suspendable-ports) + #:use-module (sxml simple) + #:use-module (srfi srfi-19) + #:use-module (rnrs bytevectors)) + +(define (G_ text) + (let ((out (gettext text))) + (if (string=? out text) + ;; No translation, disambiguate + (car (reverse (string-split text #\|))) + out))) + +(define* (same-uri? a b #:key (skip-query #f)) + (and (equal? (uri-path a) (uri-path b)) + (or skip-query (equal? (uri-query a) (uri-query b))))) + +(define*-public (make-identity-provider + issuer + key-file + subject + password + jwks-uri + authorization-endpoint-uri + token-endpoint-uri + jti-list + #:key + (current-time current-time) + (http-get http-get)) + (let ((key + (catch #t + (lambda () + (call-with-input-file key-file stubs:json->scm)) + (lambda error + (format (current-error-port) + (G_ "Warning: generating a new key pair.")) + (let ((k (generate-key #:n-size 2048))) + (stubs:call-with-output-file* + key-file + (lambda (port) + (stubs:scm->json k port #:pretty #t))) + k))))) + (let ((alg + (if (eq? (kty key) 'RSA) + 'RS256 + 'ES256))) + (let ((authorization-endpoint + (make-authorization-endpoint subject password alg key 120 + #:current-time current-time + #:http-get http-get)) + (token-endpoint + (make-token-endpoint token-endpoint-uri issuer alg key 3600 jti-list + #:current-time current-time)) + (openid-configuration + (make-oidc-configuration jwks-uri + authorization-endpoint-uri + token-endpoint-uri)) + (openid-configuration-uri + (build-uri 'https + #:host (uri-host issuer) + #:path "/.well-known/openid-configuration"))) + (lambda (request request-body) + (let ((uri (request-uri request)) + (current-time (current-time))) + (cond ((same-uri? uri openid-configuration-uri) + (let* ((current-sec (time-second current-time)) + (exp-sec (+ current-sec 3600)) + (exp (time-utc->date + (make-time time-utc 0 exp-sec)))) + (serve-oidc-configuration exp openid-configuration))) + ((same-uri? uri jwks-uri) + (let* ((current-sec (time-second current-time)) + (exp-sec (+ current-sec 3600)) + (exp (time-utc->date + (make-time time-utc 0 exp-sec)))) + (serve-jwks exp (make-jwks (list key))))) + ((same-uri? uri authorization-endpoint-uri #:skip-query #t) + (authorization-endpoint request request-body)) + ((same-uri? uri token-endpoint-uri) + (token-endpoint request request-body)) + ((same-uri? uri subject) + (values + (build-response #:headers '((content-type text/turtle)) + #:port #f) + (format #f + "@prefix foaf: . +@prefix rdfs: . + +<#~a> a foaf:Person ; + rdfs:comment \"It works. Now you should use another service to serve that resource.\" . +" + (uri-fragment subject)))) + (else + (values + (build-response #:code 404 + #:reason-phrase "Not Found" + #:headers '((content-type application/xhtml+xml))) + (with-output-to-string + (lambda () + (sxml->xml + `(*TOP* (*PI* xml "version=\"1.0\" encoding=\"utf-8\"") + (html (@ (xmlns "http://www.w3.org/1999/xhtml") + (xml:lang "en")) + (body + (h1 "Resource not found") + (p "This OpenID Connect identity provider does not know the resource you are requesting.")))))))))))))))) + +(define-public (main) + (define* (http-get-with-log uri #:key (headers '())) + (define date (date->string (time-utc->date (current-time)))) + (define uri-string (if (uri? uri) (uri->string uri) uri)) + (format (current-error-port) "~a: GET ~a ~s...\n" + date uri-string headers) + (receive (response response-body) (http-get uri #:headers headers) + (if response-body + (format (current-error-port) "~a: GET ~a ~s: ~s ~a bytes\n" + date uri-string headers response + (if (bytevector? response-body) + (bytevector-length response-body) + (string-length response-body))) + (format (current-error-port) "~a: GET ~a ~s: ~s\n" + date uri-string headers response)) + (values response response-body))) + (define cache-http-get + (with-cache #:http-get http-get-with-log)) + (setlocale LC_ALL "") + (bindtextdomain cfg:package cfg:localedir) + (textdomain cfg:package) + (let ((version-sym + (string->symbol (G_ "command-line|version"))) + (help-sym + (string->symbol (G_ "comand-line|help"))) + (issuer-sym + (string->symbol (G_ "comand-line|issuer"))) + (key-file-sym + (string->symbol (G_ "comand-line|key-file"))) + (subject-sym + (string->symbol (G_ "comand-line|subject"))) + (password-sym + (string->symbol (G_ "comand-line|password"))) + (jwks-uri-sym + (string->symbol (G_ "comand-line|jwks-uri"))) + (authorization-endpoint-uri-sym + (string->symbol (G_ "comand-line|authorization-endpoint-uri"))) + (token-endpoint-uri-sym + (string->symbol (G_ "comand-line|token-endpoint-uri"))) + (port-sym + (string->symbol (G_ "comand-line|port"))) + (log-file-sym + (string->symbol (G_ "comand-line|log-file"))) + (error-file-sym + (string->symbol (G_ "comand-line|error-file")))) + (let ((options + (let ((option-spec + `((,version-sym (single-char #\v) (value #f)) + (,help-sym (single-char #\h) (value #f)) + (,issuer-sym (single-char #\i) (value #t)) + (,key-file-sym (single-char #\k) (value #t)) + (,subject-sym (single-char #\s) (value #t)) + (,password-sym (single-char #\w) (value #t)) + (,jwks-uri-sym (single-char #\j) (value #t)) + (,authorization-endpoint-uri-sym (single-char #\a) (value #t)) + (,token-endpoint-uri-sym (single-char #\t) (value #t)) + (,port-sym (single-char #\p) (value #t)) + (,log-file-sym (single-char #\l) (value #t)) + (,error-file-sym (single-char #\e) (value #t))))) + (getopt-long (command-line) option-spec)))) + (cond + ((option-ref options help-sym #f) + (format #t (G_ "Usage: ~a [OPTIONS]... + +Run the Solid identity provider for a specific user. + +Options: + -h, --~a: + display this help message and exit. + -v, --~a: + display the version information (~a) and exit. + -i URI, --~a=URI: + set the public server host name. + -k FILE, --~a=FILE.jwk: + set the file name of the key file. If it does not exist, a new + key is generated. + -s WEBID, --~a=WEBID: + set the identity of the subject. + -w PASSWORD, --~a=PASSWORD: + set the password to recognize the user. + -j URI, --~a=URI: + set the URI to query the key of the server. + -a URI, --~a=URI: + set the authorization endpoint of the issuer. + -t URI, --~a=URI: + set the token endpoint of the issuer. + -p PORT, --~a=PORT: + set the port to bind (instead of 8080). + -l FILE.log, --~a=FILE.log: + dump the standard output to that file. + -e FILE.err, --~a=FILE.err: + dump the standard error to that file. + +Environment variables: + + LANG: set the locale of the sysadmin-facing interface (the user +pages are translated according to the user agent’s Accept-language +header), for log files and command-line interface. It is currently ~a. + + XDG_DATA_HOME: where to store the refresh tokens (under the +webid-oidc directory). For a system service, it is recommended to set +it to /var/lib. Currently set to ~a. + + XDG_CACHE_HOME: where to store and update the seed file for the +random number generator. If you remove it, you need to restart the +program to use a different seed. Currently set to ~a. + + HOME: if XDG_DATA_HOME or XDG_CACHE_HOME is not set, they are +computed from the value of the HOME environment variable. It is not +used otherwise. Currently set to ~a. + +Example used in webid-oidc-demo.planete-kraus.eu (except it’s managed +by shepherd in reality): + + export LANG=C + export XDG_DATA_HOME=/var/lib + export XDG_CACHE_HOME=/var/cache + webid-oidc-issuer \\ + --issuer https://webid-oidc-demo.planete-kraus.eu \\ + --key-file /var/lib/webid-oidc/issuer/key.jwk \\ + --subject https://webid-oidc-demo.planete-kraus.eu/profile/card#me \\ + --password \"$PASSWORD\" \\ + --jwks-uri https://webid-oidc-demo.planete-kraus.eu/keys \\ + --authorization-endpoint https://webid-oidc-demo.planete-kraus.eu/authorize \\ + --token-endpoint https://webid-oidc-demo.planete-kraus.eu/token \\ + --port $PORT + +If you find a bug, send a report to ~a. +") + (car (command-line)) + help-sym version-sym + cfg:version + issuer-sym key-file-sym subject-sym password-sym + jwks-uri-sym authorization-endpoint-uri-sym + token-endpoint-uri-sym port-sym log-file-sym error-file-sym + (or (getenv "LANG") "") + (or (getenv "XDG_DATA_HOME") "") + (or (getenv "XDG_CACHE_HOME") "") + (or (getenv "HOME") "") + cfg:package-bugreport)) + ((option-ref options version-sym #f) + (format #t (G_ "~a version ~a\n") + cfg:package cfg:version)) + (else + (let ((issuer (option-ref options issuer-sym #f)) + (key-file (option-ref options key-file-sym #f)) + (subject (option-ref options subject-sym #f)) + (password (option-ref options password-sym #f)) + (jwks-uri (option-ref options jwks-uri-sym #f)) + (authorization-endpoint-uri + (option-ref options authorization-endpoint-uri-sym #f)) + (token-endpoint-uri + (option-ref options token-endpoint-uri-sym #f)) + (port-string + (option-ref options port-sym "8080")) + (log-file-string + (option-ref options log-file-sym #f)) + (error-file-string + (option-ref options error-file-sym #f)) + (jti-list (make-jti-list))) + (when log-file-string + (set-current-output-port (open-output-file* log-file-string)) + (setvbuf (current-output-port) 'none)) + (when error-file-string + (set-current-error-port (open-output-file* error-file-string)) + (setvbuf (current-error-port) 'none)) + (unless (and issuer (string->uri issuer)) + (format (current-error-port) + (G_ "You need to set the issuer.\n")) + (exit 1)) + (unless key-file + (format (current-error-port) + (G_ "You need to set the file name of the key file.\n")) + (exit 1)) + (unless (and subject (string->uri subject)) + (format (current-error-port) + (G_ "You need to set the identity of the subject.\n")) + (exit 1)) + (unless password + (format (current-error-port) + (G_ "You need to set the password to verify the identity of the subject.\n")) + (exit 1)) + (unless (and jwks-uri (string->uri jwks-uri)) + (format (current-error-port) + (G_ "You need to set the JWKS URI.\n")) + (exit 1)) + (unless (and authorization-endpoint-uri + (string->uri authorization-endpoint-uri)) + (format (current-error-port) + (G_ "You need to set the authorization endpoint URI.\n")) + (exit 1)) + (unless (and token-endpoint-uri + (string->uri token-endpoint-uri)) + (format (current-error-port) + (G_ "You need to set the token endpoint URI.\n")) + (exit 1)) + (unless (and (string->number port-string) + (integer? (string->number port-string)) + (>= (string->number port-string) 0) + (<= (string->number port-string) 65535)) + (format (current-error-port) + (G_ "The port should be a number between 0 and 65535.\n")) + (exit 1)) + (let ((handler + (make-identity-provider + (string->uri issuer) + key-file + (string->uri subject) + password + (string->uri jwks-uri) + (string->uri authorization-endpoint-uri) + (string->uri token-endpoint-uri) + jti-list + #:current-time current-time + #:http-get cache-http-get))) + (let ((handler-with-log + (lambda (request request-body) + (with-exception-handler + (lambda (error) + (format (current-error-port) + (G_ "Internal server error: ~a\n") + (error->str error)) + (values + (build-response #:code 500 + #:reason-phrase "Internal Server Error") + "Sorry, there was an error.")) + (lambda () + (handler request request-body)))))) + (install-suspendable-ports!) + (run-server handler 'http (list #:port (string->number port-string))))))))))) -- cgit v1.2.3