From 209a79fc4d941560987a092f2c547a034de8db20 Mon Sep 17 00:00:00 2001 From: Vivien Kraus Date: Sat, 5 Dec 2020 13:11:49 +0100 Subject: Run the identity provider as a script --- Makefile.am | 2 + NEWS | 23 +------- bootstrap | 4 ++ doc/webid-oidc.texi | 67 +++++++++++++++++++++ man/Makefile.am | 6 +- po/fr.po | 99 +++++--------------------------- po/webid-oidc.pot | 14 ++++- src/Makefile.am | 2 + src/inst/webid-oidc/Makefile.am | 12 +++- src/pre-inst/webid-oidc/Makefile.am | 12 +++- src/scm/webid-oidc/identity-provider.scm | 26 ++++++--- src/scm/webid-oidc/stubs.scm | 4 ++ src/webid-oidc-issuer | 7 +++ 13 files changed, 155 insertions(+), 123 deletions(-) create mode 100755 src/webid-oidc-issuer diff --git a/Makefile.am b/Makefile.am index 73af906..8e8a295 100644 --- a/Makefile.am +++ b/Makefile.am @@ -11,6 +11,8 @@ ACLOCAL_AMFLAGS = -I m4 AM_CPPFLAGS = -DLOCALEDIR=\"$(localedir)\" -I. -I$(srcdir) AM_CFLAGS = $(GUILE_CFLAGS) $(NETTLE_CFLAGS) nodist_noinst_SCRIPTS = pre-inst-env +dist_bin_SCRIPTS = +libexec_SCRIPTS = INDENTED = include_HEADERS = diff --git a/NEWS b/NEWS index be617ff..6b20c10 100644 --- a/NEWS +++ b/NEWS @@ -4,28 +4,7 @@ #+email: vivien@planete-kraus.eu * Initial features -** Add base64 encoding and decoding -** A random number generator -The code provides a thread-safe, parallel, random number generator. -** Generating a key pair -There is a function to generate a RSA or ECC key pair. -** Strip a public key -In order to avoid leaking the private components of a key, the -=strip-key= function keeps only the required parts. -** Hash some data -The function =hash= takes a string, and hashes its UTF-8 encoding. -** Hash a key -In DPoP, the identity provider hashes the client's key in the access -token so that resource servers can verify that the client uses the -correct key. -** Sign and verify signatures -The function =sign= creates a signature with a known JWA, and =verify= -verifies the signature. -** Encode and decode a JWS -The decoding function lets you fetch a key for validation. -** Web cache -Since DPoP and OIDC fetch a lot of things from the internet, it is in -our interest to add a web cache. +** The identity provider server is operational. # Local Variables: # mode: org # End: diff --git a/bootstrap b/bootstrap index 4c37c0f..878bc5c 100755 --- a/bootstrap +++ b/bootstrap @@ -7,7 +7,11 @@ sed -i 's|SHELL = /bin/sh|SHELL = @SHELL@|g' po/Makefile.in.in || exit 1 mkdir -p .native || exit 1 cd .native || exit 1 bash ../configure SHELL=$(which sh) || exit 1 +cp ../src/webid-oidc-issuer ../src/webid-oidc-issuer.bak || exit 1 +sed -i "s|/usr/local/bin/guile|$(which guile)|g" ../src/webid-oidc-issuer || exit 1 make -j V=1 || exit 1 make -j dist || exit 1 +chmod u+w ../src/webid-oidc-issuer || exit 1 +cp ../src/webid-oidc-issuer.bak ../src/webid-oidc-issuer || exit 1 cd .. || exit 1 rm -rf .native || exit 1 diff --git a/doc/webid-oidc.texi b/doc/webid-oidc.texi index a33da87..edea16d 100644 --- a/doc/webid-oidc.texi +++ b/doc/webid-oidc.texi @@ -49,6 +49,7 @@ Free Documentation License'' * Decentralized Authentication on the Web:: * The Json Web Token:: * Caching on server side:: +* Running an Identity Provider:: * Exceptional conditions:: * GNU Free Documentation License:: * Index:: @@ -366,6 +367,72 @@ The back-end function, @var{http-get}, defaults to that of @emph{(web client)}. @end deffn +@node Running an Identity Provider +@chapter Running an Identity Provider + +This project is packaged with a barebones identity provider. It has an +authorization endpoint and a token endpoint (and it serves its public +keys), but it is only intended for one specific person. + +You can start it by invoking the @code{webid-oidc-issuer} program, +with the following options: + +@table @asis +@item @code{-h}, or @code{--help} +prints a summary of options and exit. +@item @code{-v}, or @code{--version} +prints the version of the program and exits. +@item @code{-i @var{URI}}, or @code{--issuer=@var{URI}} +sets the global server name of the identity provider. It should have +an empty path. +@item @code{-k @var{FILE.jwk}}, or @code{--key-file=@var{FILE.jwk}} +sets the file name where to read or generate a key for the identity +provider. This file should be JSON, containing the representation of a +JWK key pair. +@item @code{-s @var{WEBID}}, or @code{--subject=@var{WEBID}} +sets the webid of the only user of the identity provider. This is an +URI, pointing to a RDF node corresponding to the user’s profile. +@item @code{-w @var{PASSWORD}}, or @code{--password=@var{PASSWORD}} +sets the password that the user must enter to authorize an +application. +@item @code{-j @var{URI}}, or @code{--jwks-uri=@var{URI}} +tells the server that requests to @var{URI} should be responded with +the public key used to sign the tokens. +@item @code{-a @var{URI}}, or @code{--authorization-endpoint-uri=@var{URI}} +tells the server that requests to @var{URI} should be treated as +authorization requests. +@item @code{-t @var{URI}}, or @code{--token-endpoint-uri=@var{URI}} +tells the server that requests to @var{URI} should be treated as token +negociation requests. +@item @code{-p @var{PORT}}, or @code{--port=@var{PORT}} +change the port number used by the server. By default, it is set to +8080. +@item @code{-l @var{FILE.log}}, or @code{--log-file=@var{FILE.log}} +let the server dump all its output to @var{FILE.log}. Since I don’t +know how to deal with syslog, this is the only way to keep logs with a +shepherd service. +@item @code{-e @var{FILE.err}}, or @code{--error-file=@var{FILE.err}} +let the server dump all its errors to @var{FILE.err}. +@end table + +The program is sensitive to the environment variables. The most +important one is @emph{LANG}, which influences how the program is +internationalized to the server administrator (the pages served to the +user use the user agent’s locale). This changes the long form of the +options, and the language in the log files. + +The @emph{XDG_DATA_HOME} should point to some place where the program +will store refresh tokens, under the @code{webid-oidc} directory. For +a system service, you might want to define that environment to +@code{/var/lib}, for instance. + +The @emph{XDG_CACHE_HOME} should point to a directory where to store +the seed of the random number generator (under a @code{webid-oidc} +directory, again). Changing the seed only happens when a program +starts to require the random number generator. You can safely delete +this directory, but you need to restart the program to actually change +the seed. + @node Exceptional conditions @chapter Exceptional conditions diff --git a/man/Makefile.am b/man/Makefile.am index 4008ab9..ac01459 100644 --- a/man/Makefile.am +++ b/man/Makefile.am @@ -1,3 +1,7 @@ -dist_man8_MANS = +dist_man8_MANS = webid-oidc-issuer.man EXTRA_DIST = ./reset-env + +webid-oidc-issuer.man: ../src/scm/webid-oidc/identity-provider.scm ../configure.ac + $(AM_V_GEN) ../pre-inst-env ./reset-env $(HELP2MAN) $(srcdir)/../src/webid-oidc-issuer > $@-t + mv $@-t $(srcdir)/$@ diff --git a/po/fr.po b/po/fr.po index 4713516..e9fdaa3 100644 --- a/po/fr.po +++ b/po/fr.po @@ -750,77 +750,7 @@ 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" +#, scheme-format msgid "" "Usage: ~a [OPTIONS]...\n" "\n" @@ -883,9 +813,10 @@ msgid "" " --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/" +" --authorization-endpoint-uri https://webid-oidc-demo.planete-kraus.eu/" "authorize \\\n" -" --token-endpoint https://webid-oidc-demo.planete-kraus.eu/token \\\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" @@ -1002,11 +933,19 @@ 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" +#, scheme-format +msgid "~a: Internal server error: ~a\n" msgstr "~a : Erreur interne du serveur : ~a\n" +#: src/scm/webid-oidc/identity-provider.scm:357 +#, scheme-format +msgid "" +"The client locale ~s can’t be approximated by system locale ~s (because ~a), " +"using C.\n" +msgstr "" +"La locale du client ~s ne peut pas être approchée par la locale système ~s " +"(parce que ~a), on utilise C.\n" + #: src/scm/webid-oidc/authorization-page-unsafe.scm:29 msgid "xml-lang|en" msgstr "fr" @@ -1232,14 +1171,6 @@ msgstr "" #~ msgid "there is an external error" #~ msgstr "il y a une erreur externe" -#, scheme-format -#~ msgid "" -#~ "The client locale ~s can’t be approximated by system locale ~s (because " -#~ "~a), using C.\n" -#~ msgstr "" -#~ "La locale du client ~s ne peut pas être approchée par la locale système " -#~ "~s (parce que ~a), on utilise C.\n" - #, scheme-format #~ msgid "~a: authentication failure: ~a\n" #~ msgstr "~a : échec d’authentificationn : ~a\n" diff --git a/po/webid-oidc.pot b/po/webid-oidc.pot index 1516073..9168393 100644 --- a/po/webid-oidc.pot +++ b/po/webid-oidc.pot @@ -796,9 +796,10 @@ msgid "" " --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/" +" --authorization-endpoint-uri https://webid-oidc-demo.planete-kraus.eu/" "authorize \\\n" -" --token-endpoint https://webid-oidc-demo.planete-kraus.eu/token \\\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" @@ -843,7 +844,14 @@ msgstr "" #: src/scm/webid-oidc/identity-provider.scm:346 #, scheme-format -msgid "Internal server error: ~a\n" +msgid "~a: Internal server error: ~a\n" +msgstr "" + +#: src/scm/webid-oidc/identity-provider.scm:357 +#, scheme-format +msgid "" +"The client locale ~s can’t be approximated by system locale ~s (because ~a), " +"using C.\n" msgstr "" #: src/scm/webid-oidc/authorization-page-unsafe.scm:29 diff --git a/src/Makefile.am b/src/Makefile.am index 72181cb..83d4a04 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,5 +1,7 @@ lib_LTLIBRARIES += %reldir%/libwebidoidc.la +dist_bin_SCRIPTS += %reldir%/webid-oidc-issuer + AM_CPPFLAGS += -I %reldir% -I $(srcdir)/%reldir% GUILD_OPTIONS = diff --git a/src/inst/webid-oidc/Makefile.am b/src/inst/webid-oidc/Makefile.am index ac2778b..c6edc5c 100644 --- a/src/inst/webid-oidc/Makefile.am +++ b/src/inst/webid-oidc/Makefile.am @@ -2,6 +2,12 @@ webidoidcmod_DATA += %reldir%/config.scm webidoidcgo_DATA += %reldir%/config.go %reldir%/config.scm: $(top_builddir)/config.status - $(AM_V_GEN) mkdir -p %reldir% && (echo "(define-module (webid-oidc config))" ; \ - echo "(define-public libdir \"$(libdir)\")") \ - > $@-t && mv $@-t $@ + $(AM_V_GEN) mkdir -p %reldir% \ + && (echo "(define-module (webid-oidc config))" ; \ + echo "(define-public libdir \"$(libdir)\")" ; \ + echo "(define-public localedir \"$(localedir)\")" ; \ + echo "(define-public version \"$(VERSION)\")" ; \ + echo "(define-public package \"$(PACKAGE)\")" ; \ + echo "(define-public package-bugreport \"$(PACKAGE_BUGREPORT)\")") \ + > $@-t \ + && mv $@-t $@ diff --git a/src/pre-inst/webid-oidc/Makefile.am b/src/pre-inst/webid-oidc/Makefile.am index fa8c4e1..0503c8d 100644 --- a/src/pre-inst/webid-oidc/Makefile.am +++ b/src/pre-inst/webid-oidc/Makefile.am @@ -5,6 +5,12 @@ CLEANFILES += %reldir%/config.go %reldir%/config.scm BUILT_SOURCES += %reldir%/config.scm %reldir%/config.scm: $(top_builddir)/config.status - $(AM_V_GEN) mkdir -p %reldir% && (echo "(define-module (webid-oidc config))" ; \ - echo "(define-public libdir \"$(abs_top_builddir)/src/.libs\")") \ - > $@-t && mv $@-t $@ + $(AM_V_GEN) mkdir -p %reldir% \ + && (echo "(define-module (webid-oidc config))" ; \ + echo "(define-public libdir \"$(abs_top_builddir)/src/.libs\")" ; \ + echo "(define-public localedir \"$(localedir)\")" ; \ + echo "(define-public version \"$(VERSION)\")" ; \ + echo "(define-public package \"$(PACKAGE)\")" ; \ + echo "(define-public package-bugreport \"$(PACKAGE_BUGREPORT)\")") \ + > $@-t \ + && mv $@-t $@ diff --git a/src/scm/webid-oidc/identity-provider.scm b/src/scm/webid-oidc/identity-provider.scm index de49fc5..8df4386 100644 --- a/src/scm/webid-oidc/identity-provider.scm +++ b/src/scm/webid-oidc/identity-provider.scm @@ -246,8 +246,8 @@ by shepherd in reality): --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 \\ + --authorization-endpoint-uri https://webid-oidc-demo.planete-kraus.eu/authorize \\ + --token-endpoint-uri https://webid-oidc-demo.planete-kraus.eu/token \\ --port $PORT If you find a bug, send a report to ~a. @@ -284,10 +284,10 @@ If you find a bug, send a report to ~a. (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)) + (set-current-output-port (stubs: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)) + (set-current-error-port (stubs:open-output-file* error-file-string)) (setvbuf (current-error-port) 'none)) (unless (and issuer (string->uri issuer)) (format (current-error-port) @@ -343,13 +343,25 @@ If you find a bug, send a report to ~a. (with-exception-handler (lambda (error) (format (current-error-port) - (G_ "Internal server error: ~a\n") + (G_ "~a: Internal server error: ~a\n") + (date->string (time-utc->date (current-time))) (error->str error)) (values (build-response #:code 500 #:reason-phrase "Internal Server Error") "Sorry, there was an error.")) (lambda () - (handler request request-body)))))) + (with-exception-handler + (lambda (error) + (format (current-error-port) + (G_ "The client locale ~s can’t be approximated by system locale ~s (because ~a), using C.\n") + ((record-accessor &unknown-client-locale 'web-locale) error) + ((record-accessor &unknown-client-locale 'c-locale) error) + (error->str error))) + (lambda () + (handler request request-body)) + #:unwind? #t + #:unwind-for-type &unknown-client-locale)) + #:unwind? #t)))) (install-suspendable-ports!) - (run-server handler 'http (list #:port (string->number port-string))))))))))) + (run-server handler-with-log 'http (list #:port (string->number port-string))))))))))) diff --git a/src/scm/webid-oidc/stubs.scm b/src/scm/webid-oidc/stubs.scm index 831a88d..6ac5c3c 100644 --- a/src/scm/webid-oidc/stubs.scm +++ b/src/scm/webid-oidc/stubs.scm @@ -137,6 +137,10 @@ (else (throw key subr message args rest)))))) +(define-public (open-output-file* filename . args) + (mkdir-p (dirname filename)) + (apply open-output-file filename args)) + (define-public (call-with-output-file* filename . args) (mkdir-p (dirname filename)) (apply call-with-output-file filename args)) diff --git a/src/webid-oidc-issuer b/src/webid-oidc-issuer new file mode 100755 index 0000000..6dd2960 --- /dev/null +++ b/src/webid-oidc-issuer @@ -0,0 +1,7 @@ +#!/usr/local/bin/guile \ +--no-auto-compile -s +!# + +(use-modules (webid-oidc identity-provider)) + +(main) -- cgit v1.2.3