kibi-swipl-linux-x64-gnu 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -0
- package/bin/swipl +0 -0
- package/bin/swipl-win +0 -0
- package/build-manifest.json +70 -0
- package/lib/cmake/swipl/SWIPLConfig.cmake +21 -0
- package/lib/cmake/swipl/SWIPLConfigVersion.cmake +65 -0
- package/lib/cmake/swipl/SWIPLTargets-release.cmake +28 -0
- package/lib/cmake/swipl/SWIPLTargets.cmake +109 -0
- package/lib/swipl/ABI +1 -0
- package/lib/swipl/LICENSE +41 -0
- package/lib/swipl/README.md +116 -0
- package/lib/swipl/app/README.md +25 -0
- package/lib/swipl/app/app.pl +87 -0
- package/lib/swipl/app/pack.pl +350 -0
- package/lib/swipl/app/qlf.pl +521 -0
- package/lib/swipl/app/splfr.pl +177 -0
- package/lib/swipl/app/sys.pl +310 -0
- package/lib/swipl/bin/swipl.home +1 -0
- package/lib/swipl/boot/apply.pl +73 -0
- package/lib/swipl/boot/attvar.pl +344 -0
- package/lib/swipl/boot/autoload.pl +1226 -0
- package/lib/swipl/boot/bags.pl +283 -0
- package/lib/swipl/boot/dcg.pl +388 -0
- package/lib/swipl/boot/dicts.pl +193 -0
- package/lib/swipl/boot/dwim.pl +485 -0
- package/lib/swipl/boot/engines.pl +152 -0
- package/lib/swipl/boot/expand.pl +1628 -0
- package/lib/swipl/boot/gc.pl +65 -0
- package/lib/swipl/boot/history.pl +304 -0
- package/lib/swipl/boot/init.pl +4682 -0
- package/lib/swipl/boot/iri.pl +64 -0
- package/lib/swipl/boot/license.pl +390 -0
- package/lib/swipl/boot/load.pl +81 -0
- package/lib/swipl/boot/messages.pl +2521 -0
- package/lib/swipl/boot/packs.pl +306 -0
- package/lib/swipl/boot/predopts.pl +154 -0
- package/lib/swipl/boot/qlf.pl +141 -0
- package/lib/swipl/boot/rc.pl +263 -0
- package/lib/swipl/boot/syspred.pl +1634 -0
- package/lib/swipl/boot/tabling.pl +2321 -0
- package/lib/swipl/boot/threads.pl +42 -0
- package/lib/swipl/boot/toplevel.pl +2248 -0
- package/lib/swipl/boot/topvars.pl +261 -0
- package/lib/swipl/boot.prc +0 -0
- package/lib/swipl/cmake/swipl.cmake +131 -0
- package/lib/swipl/customize/README.md +23 -0
- package/lib/swipl/customize/edit +101 -0
- package/lib/swipl/customize/init.pl +164 -0
- package/lib/swipl/demo/README.md +33 -0
- package/lib/swipl/demo/likes.pl +44 -0
- package/lib/swipl/doc/packages/examples/chr/bool.chr +281 -0
- package/lib/swipl/doc/packages/examples/chr/chrdif.chr +87 -0
- package/lib/swipl/doc/packages/examples/chr/chrfreeze.chr +6 -0
- package/lib/swipl/doc/packages/examples/chr/family.chr +116 -0
- package/lib/swipl/doc/packages/examples/chr/fib.chr +24 -0
- package/lib/swipl/doc/packages/examples/chr/fibonacci.chr +31 -0
- package/lib/swipl/doc/packages/examples/chr/gcd.chr +28 -0
- package/lib/swipl/doc/packages/examples/chr/leq.chr +34 -0
- package/lib/swipl/doc/packages/examples/chr/listdom.chr +138 -0
- package/lib/swipl/doc/packages/examples/chr/primes.chr +29 -0
- package/lib/swipl/doc/packages/examples/http/README.md +98 -0
- package/lib/swipl/doc/packages/examples/http/calc.pl +92 -0
- package/lib/swipl/doc/packages/examples/http/demo_body.pl +232 -0
- package/lib/swipl/doc/packages/examples/http/demo_client.pl +165 -0
- package/lib/swipl/doc/packages/examples/http/demo_daemon.pl +38 -0
- package/lib/swipl/doc/packages/examples/http/demo_files.pl +50 -0
- package/lib/swipl/doc/packages/examples/http/demo_hello.pl +15 -0
- package/lib/swipl/doc/packages/examples/http/demo_login.pl +280 -0
- package/lib/swipl/doc/packages/examples/http/demo_openid.pl +177 -0
- package/lib/swipl/doc/packages/examples/http/demo_pwp.pl +20 -0
- package/lib/swipl/doc/packages/examples/http/demo_rest.pl +56 -0
- package/lib/swipl/doc/packages/examples/http/demo_threads.pl +52 -0
- package/lib/swipl/doc/packages/examples/http/linux-init-script +126 -0
- package/lib/swipl/doc/packages/examples/http/pwp/context.pwp +23 -0
- package/lib/swipl/doc/packages/examples/http/pwp/index.pwp +25 -0
- package/lib/swipl/doc/packages/examples/http/pwp/pwp1.pwp +12 -0
- package/lib/swipl/doc/packages/examples/http/pwp/pwp2.pwp +10 -0
- package/lib/swipl/doc/packages/examples/http/pwp/pwp3.pwp +25 -0
- package/lib/swipl/doc/packages/examples/http/pwp/pwp4.pwp +23 -0
- package/lib/swipl/doc/packages/examples/http/pwp/pwp5.pwp +11 -0
- package/lib/swipl/doc/packages/examples/http/pwp/pwp6.pwp +3 -0
- package/lib/swipl/doc/packages/examples/http/pwp/pwp7.pwp +3 -0
- package/lib/swipl/doc/packages/examples/http/pwp/pwp8.pwp +3 -0
- package/lib/swipl/doc/packages/examples/http/pwp/pwpdb.pl +12 -0
- package/lib/swipl/doc/packages/examples/http/systemd-script.service +18 -0
- package/lib/swipl/doc/packages/examples/http/upstart-script.conf +20 -0
- package/lib/swipl/doc/packages/examples/plunit/read.pl +17 -0
- package/lib/swipl/doc/packages/examples/plunit/simple.pl +33 -0
- package/lib/swipl/doc/packages/examples/ssl/client.pl +83 -0
- package/lib/swipl/doc/packages/examples/ssl/etc/README +52 -0
- package/lib/swipl/doc/packages/examples/ssl/etc/client/client-cert.p12 +0 -0
- package/lib/swipl/doc/packages/examples/ssl/etc/client/client-cert.pem +85 -0
- package/lib/swipl/doc/packages/examples/ssl/etc/client/client-key.pem +30 -0
- package/lib/swipl/doc/packages/examples/ssl/etc/demoCA/cacert.pem +82 -0
- package/lib/swipl/doc/packages/examples/ssl/etc/demoCA/careq.pem +18 -0
- package/lib/swipl/doc/packages/examples/ssl/etc/demoCA/crlnumber +1 -0
- package/lib/swipl/doc/packages/examples/ssl/etc/demoCA/index.txt +3 -0
- package/lib/swipl/doc/packages/examples/ssl/etc/demoCA/index.txt.attr +1 -0
- package/lib/swipl/doc/packages/examples/ssl/etc/demoCA/newcerts/9DC08797A0F63F7C.pem +85 -0
- package/lib/swipl/doc/packages/examples/ssl/etc/demoCA/newcerts/9DC08797A0F63F7D.pem +85 -0
- package/lib/swipl/doc/packages/examples/ssl/etc/demoCA/private/cakey.pem +30 -0
- package/lib/swipl/doc/packages/examples/ssl/etc/demoCA/serial +1 -0
- package/lib/swipl/doc/packages/examples/ssl/etc/server/server-cert.pem +85 -0
- package/lib/swipl/doc/packages/examples/ssl/etc/server/server-key.pem +30 -0
- package/lib/swipl/doc/packages/examples/ssl/https.pl +267 -0
- package/lib/swipl/doc/packages/examples/ssl/server.pl +106 -0
- package/lib/swipl/include/SWI-Prolog.h +1544 -0
- package/lib/swipl/include/SWI-Stream.h +537 -0
- package/lib/swipl/include/Yap/YapInterface.h +283 -0
- package/lib/swipl/include/sicstus/sicstus.h +452 -0
- package/lib/swipl/lib/x86_64-linux/cgi.so +0 -0
- package/lib/swipl/lib/x86_64-linux/crypt.so +0 -0
- package/lib/swipl/lib/x86_64-linux/crypto4pl.so +0 -0
- package/lib/swipl/lib/x86_64-linux/double_metaphone.so +0 -0
- package/lib/swipl/lib/x86_64-linux/files.so +0 -0
- package/lib/swipl/lib/x86_64-linux/hashstream.so +0 -0
- package/lib/swipl/lib/x86_64-linux/http_stream.so +0 -0
- package/lib/swipl/lib/x86_64-linux/isub.so +0 -0
- package/lib/swipl/lib/x86_64-linux/json.so +0 -0
- package/lib/swipl/lib/x86_64-linux/libswipl.so.10 +0 -0
- package/lib/swipl/lib/x86_64-linux/mallocinfo.so +0 -0
- package/lib/swipl/lib/x86_64-linux/md54pl.so +0 -0
- package/lib/swipl/lib/x86_64-linux/memfile.so +0 -0
- package/lib/swipl/lib/x86_64-linux/ntriples.so +0 -0
- package/lib/swipl/lib/x86_64-linux/pcre4pl.so +0 -0
- package/lib/swipl/lib/x86_64-linux/porter_stem.so +0 -0
- package/lib/swipl/lib/x86_64-linux/process.so +0 -0
- package/lib/swipl/lib/x86_64-linux/prolog_stream.so +0 -0
- package/lib/swipl/lib/x86_64-linux/rdf_db.so +0 -0
- package/lib/swipl/lib/x86_64-linux/readutil.so +0 -0
- package/lib/swipl/lib/x86_64-linux/rlimit.so +0 -0
- package/lib/swipl/lib/x86_64-linux/sched.so +0 -0
- package/lib/swipl/lib/x86_64-linux/sgml2pl.so +0 -0
- package/lib/swipl/lib/x86_64-linux/sha4pl.so +0 -0
- package/lib/swipl/lib/x86_64-linux/snowball.so +0 -0
- package/lib/swipl/lib/x86_64-linux/socket.so +0 -0
- package/lib/swipl/lib/x86_64-linux/ssl4pl.so +0 -0
- package/lib/swipl/lib/x86_64-linux/streaminfo.so +0 -0
- package/lib/swipl/lib/x86_64-linux/syslog.so +0 -0
- package/lib/swipl/lib/x86_64-linux/time.so +0 -0
- package/lib/swipl/lib/x86_64-linux/turtle.so +0 -0
- package/lib/swipl/lib/x86_64-linux/uid.so +0 -0
- package/lib/swipl/lib/x86_64-linux/unix.so +0 -0
- package/lib/swipl/lib/x86_64-linux/uri.so +0 -0
- package/lib/swipl/lib/x86_64-linux/websocket.so +0 -0
- package/lib/swipl/lib/x86_64-linux/zlib4pl.so +0 -0
- package/lib/swipl/library/INDEX.pl +1020 -0
- package/lib/swipl/library/aggregate.pl +755 -0
- package/lib/swipl/library/ansi_term.pl +653 -0
- package/lib/swipl/library/apply.pl +426 -0
- package/lib/swipl/library/apply_macros.pl +497 -0
- package/lib/swipl/library/arithmetic.pl +320 -0
- package/lib/swipl/library/assoc.pl +522 -0
- package/lib/swipl/library/atom.pl +169 -0
- package/lib/swipl/library/backcomp.pl +688 -0
- package/lib/swipl/library/base32.pl +291 -0
- package/lib/swipl/library/base64.pl +441 -0
- package/lib/swipl/library/broadcast.pl +161 -0
- package/lib/swipl/library/build/cmake.pl +137 -0
- package/lib/swipl/library/build/conan.pl +232 -0
- package/lib/swipl/library/build/make.pl +168 -0
- package/lib/swipl/library/build/tools.pl +825 -0
- package/lib/swipl/library/charsio.pl +195 -0
- package/lib/swipl/library/check.pl +1097 -0
- package/lib/swipl/library/check_installation.pl +912 -0
- package/lib/swipl/library/clp/INDEX.pl +157 -0
- package/lib/swipl/library/clp/bounds.pl +2036 -0
- package/lib/swipl/library/clp/clp_distinct.pl +263 -0
- package/lib/swipl/library/clp/clp_events.pl +92 -0
- package/lib/swipl/library/clp/clpb.pl +1896 -0
- package/lib/swipl/library/clp/clpfd.pl +7906 -0
- package/lib/swipl/library/clp/simplex.pl +1580 -0
- package/lib/swipl/library/codesio.pl +182 -0
- package/lib/swipl/library/coinduction.pl +183 -0
- package/lib/swipl/library/console_input.pl +289 -0
- package/lib/swipl/library/csv.pl +611 -0
- package/lib/swipl/library/ctypes.pl +161 -0
- package/lib/swipl/library/date.pl +370 -0
- package/lib/swipl/library/dcg/INDEX.pl +35 -0
- package/lib/swipl/library/dcg/basics.pl +514 -0
- package/lib/swipl/library/dcg/high_order.pl +227 -0
- package/lib/swipl/library/debug.pl +499 -0
- package/lib/swipl/library/dialect/bim.pl +186 -0
- package/lib/swipl/library/dialect/commons.pl +77 -0
- package/lib/swipl/library/dialect/eclipse/test_util_iso.pl +355 -0
- package/lib/swipl/library/dialect/hprolog/format.pl +44 -0
- package/lib/swipl/library/dialect/hprolog.pl +314 -0
- package/lib/swipl/library/dialect/ifprolog.pl +1317 -0
- package/lib/swipl/library/dialect/iso/iso_predicates.pl +277 -0
- package/lib/swipl/library/dialect/sicstus/README.TXT +1 -0
- package/lib/swipl/library/dialect/sicstus/arrays.pl +121 -0
- package/lib/swipl/library/dialect/sicstus/block.pl +278 -0
- package/lib/swipl/library/dialect/sicstus/lists.pl +167 -0
- package/lib/swipl/library/dialect/sicstus/ordsets.pl +52 -0
- package/lib/swipl/library/dialect/sicstus/sockets.pl +174 -0
- package/lib/swipl/library/dialect/sicstus/system.pl +262 -0
- package/lib/swipl/library/dialect/sicstus/terms.pl +57 -0
- package/lib/swipl/library/dialect/sicstus/timeout.pl +92 -0
- package/lib/swipl/library/dialect/sicstus.pl +582 -0
- package/lib/swipl/library/dialect/sicstus4/aggregate.pl +60 -0
- package/lib/swipl/library/dialect/sicstus4/between.pl +62 -0
- package/lib/swipl/library/dialect/sicstus4/clpfd.pl +75 -0
- package/lib/swipl/library/dialect/sicstus4/file_systems.pl +413 -0
- package/lib/swipl/library/dialect/sicstus4/lists.pl +274 -0
- package/lib/swipl/library/dialect/sicstus4/ordsets.pl +54 -0
- package/lib/swipl/library/dialect/sicstus4/samsort.pl +86 -0
- package/lib/swipl/library/dialect/sicstus4/sets.pl +124 -0
- package/lib/swipl/library/dialect/sicstus4/sockets.pl +164 -0
- package/lib/swipl/library/dialect/sicstus4/system.pl +80 -0
- package/lib/swipl/library/dialect/sicstus4/terms.pl +89 -0
- package/lib/swipl/library/dialect/sicstus4/timeout.pl +43 -0
- package/lib/swipl/library/dialect/sicstus4/types.pl +103 -0
- package/lib/swipl/library/dialect/sicstus4.pl +200 -0
- package/lib/swipl/library/dialect/swi/syspred_options.pl +250 -0
- package/lib/swipl/library/dialect/xsb/README.md +20 -0
- package/lib/swipl/library/dialect/xsb/basics.pl +318 -0
- package/lib/swipl/library/dialect/xsb/consult.pl +87 -0
- package/lib/swipl/library/dialect/xsb/curr_sym.pl +57 -0
- package/lib/swipl/library/dialect/xsb/error_handler.pl +111 -0
- package/lib/swipl/library/dialect/xsb/gensym.pl +53 -0
- package/lib/swipl/library/dialect/xsb/gpp.pl +138 -0
- package/lib/swipl/library/dialect/xsb/intern.pl +48 -0
- package/lib/swipl/library/dialect/xsb/lists.pl +47 -0
- package/lib/swipl/library/dialect/xsb/machine.pl +295 -0
- package/lib/swipl/library/dialect/xsb/ordsets.pl +53 -0
- package/lib/swipl/library/dialect/xsb/setof.pl +54 -0
- package/lib/swipl/library/dialect/xsb/source.pl +308 -0
- package/lib/swipl/library/dialect/xsb/standard.pl +169 -0
- package/lib/swipl/library/dialect/xsb/storage.pl +70 -0
- package/lib/swipl/library/dialect/xsb/string.pl +76 -0
- package/lib/swipl/library/dialect/xsb/thread.pl +62 -0
- package/lib/swipl/library/dialect/xsb/timed_call.pl +158 -0
- package/lib/swipl/library/dialect/xsb.pl +688 -0
- package/lib/swipl/library/dialect/yap/README.TXT +8 -0
- package/lib/swipl/library/dialect/yap.pl +283 -0
- package/lib/swipl/library/dialect.pl +123 -0
- package/lib/swipl/library/dicts.pl +399 -0
- package/lib/swipl/library/dif.pl +426 -0
- package/lib/swipl/library/edinburgh.pl +138 -0
- package/lib/swipl/library/edit.pl +783 -0
- package/lib/swipl/library/error.pl +495 -0
- package/lib/swipl/library/exceptions.pl +231 -0
- package/lib/swipl/library/explain.pl +543 -0
- package/lib/swipl/library/ext/RDF/INDEX.pl +25 -0
- package/lib/swipl/library/ext/RDF/rdf.pl +450 -0
- package/lib/swipl/library/ext/RDF/rdf_parser.pl +649 -0
- package/lib/swipl/library/ext/RDF/rdf_triple.pl +448 -0
- package/lib/swipl/library/ext/RDF/rdf_write.pl +701 -0
- package/lib/swipl/library/ext/RDF/rewrite_term.pl +177 -0
- package/lib/swipl/library/ext/chr/chr/a_star.pl +80 -0
- package/lib/swipl/library/ext/chr/chr/binomialheap.pl +142 -0
- package/lib/swipl/library/ext/chr/chr/builtins.pl +629 -0
- package/lib/swipl/library/ext/chr/chr/chr_compiler_errors.pl +179 -0
- package/lib/swipl/library/ext/chr/chr/chr_compiler_options.pl +382 -0
- package/lib/swipl/library/ext/chr/chr/chr_compiler_utility.pl +338 -0
- package/lib/swipl/library/ext/chr/chr/chr_debug.pl +59 -0
- package/lib/swipl/library/ext/chr/chr/chr_hashtable_store.pl +425 -0
- package/lib/swipl/library/ext/chr/chr/chr_integertable_store.pl +139 -0
- package/lib/swipl/library/ext/chr/chr/chr_messages.pl +176 -0
- package/lib/swipl/library/ext/chr/chr/chr_op.pl +53 -0
- package/lib/swipl/library/ext/chr/chr/chr_runtime.pl +1016 -0
- package/lib/swipl/library/ext/chr/chr/chr_translate.pl +25424 -0
- package/lib/swipl/library/ext/chr/chr/clean_code.pl +252 -0
- package/lib/swipl/library/ext/chr/chr/find.pl +78 -0
- package/lib/swipl/library/ext/chr/chr/guard_entailment.pl +19432 -0
- package/lib/swipl/library/ext/chr/chr/listmap.pl +108 -0
- package/lib/swipl/library/ext/chr/chr/pairlist.pl +78 -0
- package/lib/swipl/library/ext/chr/chr.pl +686 -0
- package/lib/swipl/library/ext/clib/INDEX.pl +158 -0
- package/lib/swipl/library/ext/clib/cgi.pl +86 -0
- package/lib/swipl/library/ext/clib/crypt.pl +44 -0
- package/lib/swipl/library/ext/clib/filesex.pl +644 -0
- package/lib/swipl/library/ext/clib/hash_stream.pl +119 -0
- package/lib/swipl/library/ext/clib/mallocinfo.pl +138 -0
- package/lib/swipl/library/ext/clib/md5.pl +68 -0
- package/lib/swipl/library/ext/clib/memfile.pl +61 -0
- package/lib/swipl/library/ext/clib/process.pl +573 -0
- package/lib/swipl/library/ext/clib/prolog_server.pl +157 -0
- package/lib/swipl/library/ext/clib/prolog_stream.pl +80 -0
- package/lib/swipl/library/ext/clib/rlimit.pl +54 -0
- package/lib/swipl/library/ext/clib/sched.pl +85 -0
- package/lib/swipl/library/ext/clib/sha.pl +162 -0
- package/lib/swipl/library/ext/clib/socket.pl +1102 -0
- package/lib/swipl/library/ext/clib/streaminfo.pl +103 -0
- package/lib/swipl/library/ext/clib/streampool.pl +136 -0
- package/lib/swipl/library/ext/clib/syslog.pl +180 -0
- package/lib/swipl/library/ext/clib/time.pl +194 -0
- package/lib/swipl/library/ext/clib/udp_broadcast.pl +975 -0
- package/lib/swipl/library/ext/clib/uid.pl +220 -0
- package/lib/swipl/library/ext/clib/unix.pl +317 -0
- package/lib/swipl/library/ext/clib/uri.pl +530 -0
- package/lib/swipl/library/ext/clib/uuid.pl +207 -0
- package/lib/swipl/library/ext/http/http/INDEX.pl +266 -0
- package/lib/swipl/library/ext/http/http/README.md +34 -0
- package/lib/swipl/library/ext/http/http/ax.pl +189 -0
- package/lib/swipl/library/ext/http/http/dcg_basics.pl +49 -0
- package/lib/swipl/library/ext/http/http/graphql.pl +1367 -0
- package/lib/swipl/library/ext/http/http/html_decl.pl +416 -0
- package/lib/swipl/library/ext/http/http/html_head.pl +654 -0
- package/lib/swipl/library/ext/http/http/html_quasiquotations.pl +120 -0
- package/lib/swipl/library/ext/http/http/html_write.pl +1425 -0
- package/lib/swipl/library/ext/http/http/htmx.pl +139 -0
- package/lib/swipl/library/ext/http/http/http_authenticate.pl +364 -0
- package/lib/swipl/library/ext/http/http/http_client.pl +412 -0
- package/lib/swipl/library/ext/http/http/http_cookie.pl +245 -0
- package/lib/swipl/library/ext/http/http/http_cors.pl +176 -0
- package/lib/swipl/library/ext/http/http/http_digest.pl +820 -0
- package/lib/swipl/library/ext/http/http/http_dirindex.pl +296 -0
- package/lib/swipl/library/ext/http/http/http_dispatch.pl +1552 -0
- package/lib/swipl/library/ext/http/http/http_dyn_workers.pl +214 -0
- package/lib/swipl/library/ext/http/http/http_error.pl +126 -0
- package/lib/swipl/library/ext/http/http/http_exception.pl +225 -0
- package/lib/swipl/library/ext/http/http/http_files.pl +163 -0
- package/lib/swipl/library/ext/http/http/http_header.pl +2820 -0
- package/lib/swipl/library/ext/http/http/http_hook.pl +106 -0
- package/lib/swipl/library/ext/http/http/http_host.pl +204 -0
- package/lib/swipl/library/ext/http/http/http_load.pl +113 -0
- package/lib/swipl/library/ext/http/http/http_log.pl +738 -0
- package/lib/swipl/library/ext/http/http/http_multipart_plugin.pl +232 -0
- package/lib/swipl/library/ext/http/http/http_open.pl +1821 -0
- package/lib/swipl/library/ext/http/http/http_openid.pl +1561 -0
- package/lib/swipl/library/ext/http/http/http_parameters.pl +504 -0
- package/lib/swipl/library/ext/http/http/http_path.pl +380 -0
- package/lib/swipl/library/ext/http/http/http_proxy.pl +80 -0
- package/lib/swipl/library/ext/http/http/http_pwp.pl +351 -0
- package/lib/swipl/library/ext/http/http/http_redis_plugin.pl +332 -0
- package/lib/swipl/library/ext/http/http/http_server.pl +105 -0
- package/lib/swipl/library/ext/http/http/http_server_files.pl +126 -0
- package/lib/swipl/library/ext/http/http/http_server_health.pl +186 -0
- package/lib/swipl/library/ext/http/http/http_session.pl +1040 -0
- package/lib/swipl/library/ext/http/http/http_sgml_plugin.pl +137 -0
- package/lib/swipl/library/ext/http/http/http_stream.pl +376 -0
- package/lib/swipl/library/ext/http/http/http_unix_daemon.pl +989 -0
- package/lib/swipl/library/ext/http/http/http_wrapper.pl +559 -0
- package/lib/swipl/library/ext/http/http/hub.pl +600 -0
- package/lib/swipl/library/ext/http/http/js_write.pl +461 -0
- package/lib/swipl/library/ext/http/http/mimepack.pl +224 -0
- package/lib/swipl/library/ext/http/http/mimetype.pl +276 -0
- package/lib/swipl/library/ext/http/http/term_html.pl +797 -0
- package/lib/swipl/library/ext/http/http/thread_httpd.pl +1181 -0
- package/lib/swipl/library/ext/http/http/web/css/dirindex.css +24 -0
- package/lib/swipl/library/ext/http/http/web/css/openid.css +57 -0
- package/lib/swipl/library/ext/http/http/web/icons/back.png +0 -0
- package/lib/swipl/library/ext/http/http/web/icons/c.png +0 -0
- package/lib/swipl/library/ext/http/http/web/icons/compressed.png +0 -0
- package/lib/swipl/library/ext/http/http/web/icons/folder.png +0 -0
- package/lib/swipl/library/ext/http/http/web/icons/generic.png +0 -0
- package/lib/swipl/library/ext/http/http/web/icons/layout.png +0 -0
- package/lib/swipl/library/ext/http/http/web/icons/openid-logo-square.png +0 -0
- package/lib/swipl/library/ext/http/http/web/icons/openid-logo-tiny.png +0 -0
- package/lib/swipl/library/ext/http/http/websocket.pl +729 -0
- package/lib/swipl/library/ext/http/http/yadis.pl +205 -0
- package/lib/swipl/library/ext/json/INDEX.pl +36 -0
- package/lib/swipl/library/ext/json/http/INDEX.pl +16 -0
- package/lib/swipl/library/ext/json/http/http_json.pl +490 -0
- package/lib/swipl/library/ext/json/http/js_grammar.pl +53 -0
- package/lib/swipl/library/ext/json/http/json.pl +48 -0
- package/lib/swipl/library/ext/json/http/json_convert.pl +48 -0
- package/lib/swipl/library/ext/json/json.pl +1215 -0
- package/lib/swipl/library/ext/json/json_convert.pl +681 -0
- package/lib/swipl/library/ext/json/json_grammar.pl +349 -0
- package/lib/swipl/library/ext/json/json_rpc_client.pl +423 -0
- package/lib/swipl/library/ext/json/json_rpc_common.pl +104 -0
- package/lib/swipl/library/ext/json/json_rpc_server.pl +489 -0
- package/lib/swipl/library/ext/json/json_schema.pl +2111 -0
- package/lib/swipl/library/ext/nlp/INDEX.pl +15 -0
- package/lib/swipl/library/ext/nlp/double_metaphone.pl +86 -0
- package/lib/swipl/library/ext/nlp/isub.pl +162 -0
- package/lib/swipl/library/ext/nlp/porter_stem.pl +50 -0
- package/lib/swipl/library/ext/nlp/snowball.pl +97 -0
- package/lib/swipl/library/ext/pcre/INDEX.pl +17 -0
- package/lib/swipl/library/ext/pcre/pcre.pl +974 -0
- package/lib/swipl/library/ext/plunit/INDEX.pl +20 -0
- package/lib/swipl/library/ext/plunit/plunit.pl +2631 -0
- package/lib/swipl/library/ext/plunit/test_wizard.pl +249 -0
- package/lib/swipl/library/ext/semweb/semweb/INDEX.pl +288 -0
- package/lib/swipl/library/ext/semweb/semweb/rdf11.pl +2106 -0
- package/lib/swipl/library/ext/semweb/semweb/rdf11_containers.pl +299 -0
- package/lib/swipl/library/ext/semweb/semweb/rdf_cache.pl +278 -0
- package/lib/swipl/library/ext/semweb/semweb/rdf_compare.pl +132 -0
- package/lib/swipl/library/ext/semweb/semweb/rdf_db.pl +3468 -0
- package/lib/swipl/library/ext/semweb/semweb/rdf_edit.pl +1145 -0
- package/lib/swipl/library/ext/semweb/semweb/rdf_http_plugin.pl +274 -0
- package/lib/swipl/library/ext/semweb/semweb/rdf_library.pl +1021 -0
- package/lib/swipl/library/ext/semweb/semweb/rdf_litindex.pl +1035 -0
- package/lib/swipl/library/ext/semweb/semweb/rdf_ntriples.pl +422 -0
- package/lib/swipl/library/ext/semweb/semweb/rdf_persistency.pl +1576 -0
- package/lib/swipl/library/ext/semweb/semweb/rdf_portray.pl +182 -0
- package/lib/swipl/library/ext/semweb/semweb/rdf_prefixes.pl +681 -0
- package/lib/swipl/library/ext/semweb/semweb/rdf_sandbox.pl +153 -0
- package/lib/swipl/library/ext/semweb/semweb/rdf_turtle.pl +54 -0
- package/lib/swipl/library/ext/semweb/semweb/rdf_turtle_write.pl +1587 -0
- package/lib/swipl/library/ext/semweb/semweb/rdf_zlib_plugin.pl +52 -0
- package/lib/swipl/library/ext/semweb/semweb/rdfa.pl +1510 -0
- package/lib/swipl/library/ext/semweb/semweb/rdfs.pl +475 -0
- package/lib/swipl/library/ext/semweb/semweb/sparql_client.pl +643 -0
- package/lib/swipl/library/ext/semweb/semweb/turtle.pl +455 -0
- package/lib/swipl/library/ext/sgml/DTD/HTML4.dcl +88 -0
- package/lib/swipl/library/ext/sgml/DTD/HTML4.dtd +1092 -0
- package/lib/swipl/library/ext/sgml/DTD/HTML4.soc +6 -0
- package/lib/swipl/library/ext/sgml/DTD/HTML5.dtd +906 -0
- package/lib/swipl/library/ext/sgml/DTD/HTMLlat1.ent +195 -0
- package/lib/swipl/library/ext/sgml/DTD/HTMLspec.ent +77 -0
- package/lib/swipl/library/ext/sgml/DTD/HTMLsym.ent +241 -0
- package/lib/swipl/library/ext/sgml/INDEX.pl +64 -0
- package/lib/swipl/library/ext/sgml/c14n2.pl +203 -0
- package/lib/swipl/library/ext/sgml/iso_639.pl +631 -0
- package/lib/swipl/library/ext/sgml/pwp.pl +705 -0
- package/lib/swipl/library/ext/sgml/sgml.pl +815 -0
- package/lib/swipl/library/ext/sgml/sgml_write.pl +1003 -0
- package/lib/swipl/library/ext/sgml/xpath.pl +620 -0
- package/lib/swipl/library/ext/sgml/xsdp_types.pl +232 -0
- package/lib/swipl/library/ext/ssl/INDEX.pl +60 -0
- package/lib/swipl/library/ext/ssl/crypto.pl +1015 -0
- package/lib/swipl/library/ext/ssl/http/INDEX.pl +5 -0
- package/lib/swipl/library/ext/ssl/http/http_ssl_plugin.pl +296 -0
- package/lib/swipl/library/ext/ssl/saml.pl +609 -0
- package/lib/swipl/library/ext/ssl/ssl.pl +647 -0
- package/lib/swipl/library/ext/ssl/xmldsig.pl +391 -0
- package/lib/swipl/library/ext/ssl/xmlenc.pl +354 -0
- package/lib/swipl/library/ext/zlib/INDEX.pl +8 -0
- package/lib/swipl/library/ext/zlib/zlib.pl +112 -0
- package/lib/swipl/library/fastrw.pl +105 -0
- package/lib/swipl/library/files.pl +80 -0
- package/lib/swipl/library/gensym.pl +111 -0
- package/lib/swipl/library/git.pl +1027 -0
- package/lib/swipl/library/hashtable.pl +365 -0
- package/lib/swipl/library/heaps.pl +252 -0
- package/lib/swipl/library/hotfix.pl +239 -0
- package/lib/swipl/library/http/jquery.pl +103 -0
- package/lib/swipl/library/http/web/js/jquery-3.6.0.min.js +2 -0
- package/lib/swipl/library/increval.pl +217 -0
- package/lib/swipl/library/intercept.pl +263 -0
- package/lib/swipl/library/iostream.pl +237 -0
- package/lib/swipl/library/iri_scheme/file.pl +70 -0
- package/lib/swipl/library/lazy_lists.pl +481 -0
- package/lib/swipl/library/listing.pl +1362 -0
- package/lib/swipl/library/lists.pl +860 -0
- package/lib/swipl/library/lynx/INDEX.pl +14 -0
- package/lib/swipl/library/lynx/format.pl +380 -0
- package/lib/swipl/library/lynx/html_style.pl +129 -0
- package/lib/swipl/library/lynx/html_text.pl +865 -0
- package/lib/swipl/library/lynx/pldoc_style.pl +87 -0
- package/lib/swipl/library/macros.pl +451 -0
- package/lib/swipl/library/main.pl +1200 -0
- package/lib/swipl/library/make.pl +197 -0
- package/lib/swipl/library/modules.pl +129 -0
- package/lib/swipl/library/nb_rbtrees.pl +267 -0
- package/lib/swipl/library/nb_set.pl +203 -0
- package/lib/swipl/library/obfuscate.pl +115 -0
- package/lib/swipl/library/occurs.pl +241 -0
- package/lib/swipl/library/operators.pl +182 -0
- package/lib/swipl/library/option.pl +388 -0
- package/lib/swipl/library/optparse.pl +966 -0
- package/lib/swipl/library/ordsets.pl +518 -0
- package/lib/swipl/library/oset.pl +160 -0
- package/lib/swipl/library/pairs.pl +187 -0
- package/lib/swipl/library/persistency.pl +713 -0
- package/lib/swipl/library/pio.pl +47 -0
- package/lib/swipl/library/portray_text.pl +277 -0
- package/lib/swipl/library/pprint.pl +940 -0
- package/lib/swipl/library/predicate_options.pl +975 -0
- package/lib/swipl/library/prolog_autoload.pl +233 -0
- package/lib/swipl/library/prolog_breakpoints.pl +396 -0
- package/lib/swipl/library/prolog_clause.pl +1104 -0
- package/lib/swipl/library/prolog_code.pl +416 -0
- package/lib/swipl/library/prolog_codewalk.pl +1248 -0
- package/lib/swipl/library/prolog_colour.pl +3301 -0
- package/lib/swipl/library/prolog_colour.qlf +0 -0
- package/lib/swipl/library/prolog_config.pl +154 -0
- package/lib/swipl/library/prolog_coverage.pl +1333 -0
- package/lib/swipl/library/prolog_debug.pl +404 -0
- package/lib/swipl/library/prolog_deps.pl +675 -0
- package/lib/swipl/library/prolog_evaluable.pl +234 -0
- package/lib/swipl/library/prolog_format.pl +219 -0
- package/lib/swipl/library/prolog_history.pl +161 -0
- package/lib/swipl/library/prolog_jiti.pl +333 -0
- package/lib/swipl/library/prolog_locale.pl +61 -0
- package/lib/swipl/library/prolog_metainference.pl +307 -0
- package/lib/swipl/library/prolog_pack.pl +3906 -0
- package/lib/swipl/library/prolog_profile.pl +346 -0
- package/lib/swipl/library/prolog_qlfmake.pl +533 -0
- package/lib/swipl/library/prolog_source.pl +1188 -0
- package/lib/swipl/library/prolog_stack.pl +794 -0
- package/lib/swipl/library/prolog_trace.pl +365 -0
- package/lib/swipl/library/prolog_versions.pl +347 -0
- package/lib/swipl/library/prolog_wrap.pl +164 -0
- package/lib/swipl/library/prolog_xref.pl +3090 -0
- package/lib/swipl/library/prolog_xref.qlf +0 -0
- package/lib/swipl/library/pure_input.pl +266 -0
- package/lib/swipl/library/qpforeign.pl +695 -0
- package/lib/swipl/library/qsave.pl +1516 -0
- package/lib/swipl/library/quasi_quotations.pl +300 -0
- package/lib/swipl/library/quintus.pl +437 -0
- package/lib/swipl/library/random.pl +459 -0
- package/lib/swipl/library/rbtrees.pl +1153 -0
- package/lib/swipl/library/readln.pl +256 -0
- package/lib/swipl/library/readutil.pl +304 -0
- package/lib/swipl/library/record.pl +544 -0
- package/lib/swipl/library/rwlocks.pl +172 -0
- package/lib/swipl/library/sandbox.pl +1384 -0
- package/lib/swipl/library/semweb/dc.rdfs +198 -0
- package/lib/swipl/library/semweb/eor.rdfs +95 -0
- package/lib/swipl/library/semweb/owl.owl +287 -0
- package/lib/swipl/library/semweb/rdf_library.ttl +90 -0
- package/lib/swipl/library/semweb/rdfs.rdfs +251 -0
- package/lib/swipl/library/settings.pl +755 -0
- package/lib/swipl/library/shell.pl +462 -0
- package/lib/swipl/library/shlib.pl +670 -0
- package/lib/swipl/library/solution_sequences.pl +439 -0
- package/lib/swipl/library/sort.pl +119 -0
- package/lib/swipl/library/statistics.pl +541 -0
- package/lib/swipl/library/streams.pl +118 -0
- package/lib/swipl/library/strings.pl +469 -0
- package/lib/swipl/library/system.pl +95 -0
- package/lib/swipl/library/tables.pl +381 -0
- package/lib/swipl/library/tableutil.pl +771 -0
- package/lib/swipl/library/tabling.pl +42 -0
- package/lib/swipl/library/terms.pl +457 -0
- package/lib/swipl/library/theme/auto.pl +61 -0
- package/lib/swipl/library/theme/dark.pl +455 -0
- package/lib/swipl/library/theme/light.pl +45 -0
- package/lib/swipl/library/thread.pl +810 -0
- package/lib/swipl/library/thread_pool.pl +508 -0
- package/lib/swipl/library/threadutil.pl +574 -0
- package/lib/swipl/library/tty.pl +316 -0
- package/lib/swipl/library/ugraphs.pl +644 -0
- package/lib/swipl/library/unicode/INDEX.pl +6 -0
- package/lib/swipl/library/unicode/blocks.pl +414 -0
- package/lib/swipl/library/url.pl +1129 -0
- package/lib/swipl/library/utf8.pl +145 -0
- package/lib/swipl/library/varnumbers.pl +221 -0
- package/lib/swipl/library/vm.pl +251 -0
- package/lib/swipl/library/wfs.pl +205 -0
- package/lib/swipl/library/when.pl +263 -0
- package/lib/swipl/library/writef.pl +278 -0
- package/lib/swipl/library/www_browser.pl +251 -0
- package/lib/swipl/library/yall.pl +574 -0
- package/lib/swipl/library/zip.pl +211 -0
- package/lib/swipl/swipl.home +1 -0
- package/lib/vendor/libcrypto.so.3 +0 -0
- package/lib/vendor/libpcre2-8.so.0 +0 -0
- package/lib/vendor/libssl.so.3 +0 -0
- package/lib/vendor/libz.so.1 +0 -0
- package/licenses/OpenSSL-LICENSE.txt +177 -0
- package/licenses/PCRE2-COPYING +5 -0
- package/licenses/README.md +12 -0
- package/licenses/SWI-Prolog-LICENSE +41 -0
- package/licenses/zlib-LICENSE +22 -0
- package/package.json +27 -0
|
@@ -0,0 +1,820 @@
|
|
|
1
|
+
/* Part of SWI-Prolog
|
|
2
|
+
|
|
3
|
+
Author: Jan Wielemaker
|
|
4
|
+
E-mail: J.Wielemaker@vu.nl
|
|
5
|
+
WWW: http://www.swi-prolog.org
|
|
6
|
+
Copyright (c) 2015-2016, VU University Amsterdam
|
|
7
|
+
All rights reserved.
|
|
8
|
+
|
|
9
|
+
Redistribution and use in source and binary forms, with or without
|
|
10
|
+
modification, are permitted provided that the following conditions
|
|
11
|
+
are met:
|
|
12
|
+
|
|
13
|
+
1. Redistributions of source code must retain the above copyright
|
|
14
|
+
notice, this list of conditions and the following disclaimer.
|
|
15
|
+
|
|
16
|
+
2. Redistributions in binary form must reproduce the above copyright
|
|
17
|
+
notice, this list of conditions and the following disclaimer in
|
|
18
|
+
the documentation and/or other materials provided with the
|
|
19
|
+
distribution.
|
|
20
|
+
|
|
21
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
22
|
+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
23
|
+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
24
|
+
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
25
|
+
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
26
|
+
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
27
|
+
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
28
|
+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
29
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
30
|
+
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
|
31
|
+
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
32
|
+
POSSIBILITY OF SUCH DAMAGE.
|
|
33
|
+
*/
|
|
34
|
+
|
|
35
|
+
:- module(http_digest,
|
|
36
|
+
[ http_digest_challenge//2, % +Realm, +Options
|
|
37
|
+
http_digest_password_hash/4, % +User, +Realm, +Passwd, -Hash
|
|
38
|
+
% client support
|
|
39
|
+
http_parse_digest_challenge/2, % +Challenge, -Fields
|
|
40
|
+
http_digest_response/5 % +Fields, +User, +Password,
|
|
41
|
+
% -Reply +Opts
|
|
42
|
+
]).
|
|
43
|
+
:- use_module(library(http/http_authenticate)).
|
|
44
|
+
:- use_module(library(http/http_stream)).
|
|
45
|
+
:- use_module(library(dcg/basics)).
|
|
46
|
+
:- use_module(library(md5)).
|
|
47
|
+
:- use_module(library(error)).
|
|
48
|
+
:- use_module(library(option)).
|
|
49
|
+
:- use_module(library(debug)).
|
|
50
|
+
:- use_module(library(settings)).
|
|
51
|
+
:- use_module(library(base64)).
|
|
52
|
+
:- use_module(library(broadcast)).
|
|
53
|
+
:- use_module(library(uri)).
|
|
54
|
+
:- use_module(library(apply)).
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
/** <module> HTTP Digest authentication
|
|
58
|
+
|
|
59
|
+
This library implements HTTP _Digest Authentication_ as per RFC2617.
|
|
60
|
+
Unlike _Basic Authentication_, digest authentication is based on
|
|
61
|
+
challenge-response and therefore does not need to send the password over
|
|
62
|
+
the (insecure) connection. In addition, it provides a count mechanism
|
|
63
|
+
that ensure that old credentials cannot be reused, which prevents
|
|
64
|
+
attackers from using old credentials with a new request. Digest
|
|
65
|
+
authentication have the following advantages and disadvantages:
|
|
66
|
+
|
|
67
|
+
- Advantages
|
|
68
|
+
- Authentication without exchanging the password
|
|
69
|
+
- No re-use of authentication data
|
|
70
|
+
- Disadvantages
|
|
71
|
+
- An extra round trip is needed for the first authentication
|
|
72
|
+
- Server-side storage of the password is the MD5 hash of the
|
|
73
|
+
user, _realm_ and password. As MD5 hashes are quick to
|
|
74
|
+
compute, one needs strong passwords. This fixed algorithm
|
|
75
|
+
also allows for _rainbow table_ attacks, although their
|
|
76
|
+
value is limited because you need to precompute the rainbow
|
|
77
|
+
table for every server (_realm_) and user.
|
|
78
|
+
- The connection is sensitive to man-in-the-middle attack,
|
|
79
|
+
where the attacker can both change the request and response.
|
|
80
|
+
- Both client and server need to keep an administration of
|
|
81
|
+
issued _nonce_ values and associated _nonce count_ values.
|
|
82
|
+
|
|
83
|
+
And, of course, the connection itself remains insecure. Digest based
|
|
84
|
+
authentication is a viable alternative if HTTPS is not a good option and
|
|
85
|
+
security of the data itself is not an issue.
|
|
86
|
+
|
|
87
|
+
This library acts as plugin for library(http/http_dispatch), where the
|
|
88
|
+
registered handler (http_handler/3) can be given the option below to
|
|
89
|
+
initiate digest authentication.
|
|
90
|
+
|
|
91
|
+
- authentication(digest(PasswdFile, Realm))
|
|
92
|
+
|
|
93
|
+
Above, `PasswdFile` is a file containing lines of the from below, where
|
|
94
|
+
PasswordHash is computed using http_digest_password_hash/4. See also
|
|
95
|
+
library(http/http_authenticate), http_read_passwd_file/2 and
|
|
96
|
+
http_write_passwd_file/2.
|
|
97
|
+
|
|
98
|
+
==
|
|
99
|
+
User ":" PasswordHash (":" Extra)*
|
|
100
|
+
==
|
|
101
|
+
|
|
102
|
+
This library also hooks into library(http/http_open) if the option
|
|
103
|
+
authorization(digest(User, Password)) is given.
|
|
104
|
+
|
|
105
|
+
@see https://tools.ietf.org/html/rfc2617
|
|
106
|
+
*/
|
|
107
|
+
|
|
108
|
+
:- setting(nonce_timeout, number, 3600,
|
|
109
|
+
"Validity time for a server nonce").
|
|
110
|
+
:- setting(client_nonce_timeout, number, 3600,
|
|
111
|
+
"Validity time for a client nonce").
|
|
112
|
+
|
|
113
|
+
/*******************************
|
|
114
|
+
* TRACK CONNECTIONS *
|
|
115
|
+
*******************************/
|
|
116
|
+
|
|
117
|
+
:- dynamic
|
|
118
|
+
nonce_key/1, % Our nonce private key
|
|
119
|
+
nonce/2, % Nonce, CreatedTime
|
|
120
|
+
nonce_nc/3, % Nonce, NC, Time
|
|
121
|
+
nonce_nc_first/2, % Nonce, NC
|
|
122
|
+
nonce_gc_time/1. % Time of last nonce GC
|
|
123
|
+
|
|
124
|
+
%! register_nonce(+Nonce, +Created) is det.
|
|
125
|
+
%
|
|
126
|
+
% Register a nonce created by the server. We need to do so to
|
|
127
|
+
% ensure the client uses our nonce and that the connection should
|
|
128
|
+
% not considered timed out.
|
|
129
|
+
|
|
130
|
+
register_nonce(Nonce64, Created) :-
|
|
131
|
+
broadcast(http_digest(nonce(Nonce64, Created))),
|
|
132
|
+
assertz(nonce(Nonce64, Created)),
|
|
133
|
+
gc_nonce.
|
|
134
|
+
|
|
135
|
+
%! nonce_ok(+Nonce, +NC, -Stale) is semidet.
|
|
136
|
+
%
|
|
137
|
+
% True if Nonce at nonce-count NC is acceptable. That means the
|
|
138
|
+
% nonce has not timed out and we have not seen the same sequence
|
|
139
|
+
% number before. Note that requests may be concurrent and
|
|
140
|
+
% therefore NC values may not come in order.
|
|
141
|
+
|
|
142
|
+
nonce_ok(Nonce, NC, Stale) :-
|
|
143
|
+
get_time(Now),
|
|
144
|
+
nonce_not_timed_out(Nonce, Now, Stale),
|
|
145
|
+
nonce_nc_ok(Nonce, NC, Now).
|
|
146
|
+
|
|
147
|
+
nonce_not_timed_out(Nonce, Now, Stale) :-
|
|
148
|
+
( nonce(Nonce, Created)
|
|
149
|
+
-> setting(nonce_timeout, TimeOut),
|
|
150
|
+
( Now - Created < TimeOut
|
|
151
|
+
-> Stale = false
|
|
152
|
+
; forget_nonce(Nonce),
|
|
153
|
+
debug(http(nonce), 'Nonce timed out: ~q', [Nonce]),
|
|
154
|
+
Stale = true
|
|
155
|
+
)
|
|
156
|
+
; our_nonce(Nonce, _Stamp)
|
|
157
|
+
-> Stale = true
|
|
158
|
+
; debug(http(nonce), 'Unknown nonce: ~q', [Nonce]),
|
|
159
|
+
fail
|
|
160
|
+
).
|
|
161
|
+
|
|
162
|
+
nonce_nc_ok(Nonce, NC, _Now) :-
|
|
163
|
+
( nonce_nc(Nonce, NC, _)
|
|
164
|
+
; nonce_nc_first(Nonce, First),
|
|
165
|
+
NC @=< First
|
|
166
|
+
),
|
|
167
|
+
!,
|
|
168
|
+
debug(http(nonce), 'Nonce replay attempt: ~q@~q', [Nonce, NC]),
|
|
169
|
+
fail.
|
|
170
|
+
nonce_nc_ok(Nonce, NC, Now) :-
|
|
171
|
+
assertz(nonce_nc(Nonce, NC, Now)).
|
|
172
|
+
|
|
173
|
+
forget_nonce(Nonce) :-
|
|
174
|
+
retractall(nonce(Nonce, _)),
|
|
175
|
+
retractall(nonce_nc(Nonce, _, _)),
|
|
176
|
+
retractall(nonce_nc_first(Nonce, _)).
|
|
177
|
+
|
|
178
|
+
%! gc_nonce
|
|
179
|
+
%
|
|
180
|
+
% Garbage collect server nonce.
|
|
181
|
+
|
|
182
|
+
gc_nonce :-
|
|
183
|
+
nonce_gc_time(Last),
|
|
184
|
+
get_time(Now),
|
|
185
|
+
setting(nonce_timeout, TimeOut),
|
|
186
|
+
Now-Last < TimeOut/4,
|
|
187
|
+
!.
|
|
188
|
+
gc_nonce :-
|
|
189
|
+
with_mutex(http_digest_gc_nonce,
|
|
190
|
+
gc_nonce_sync).
|
|
191
|
+
|
|
192
|
+
gc_nonce_sync :-
|
|
193
|
+
get_time(Now),
|
|
194
|
+
asserta(nonce_gc_time(Now)),
|
|
195
|
+
forall(( nonce_gc_time(T),
|
|
196
|
+
T \== Now
|
|
197
|
+
),
|
|
198
|
+
retractall(nonce_gc_time(T))),
|
|
199
|
+
setting(nonce_timeout, TimeOut),
|
|
200
|
+
Before is Now - TimeOut,
|
|
201
|
+
forall(nonce_timed_out(Nonce, Before),
|
|
202
|
+
forget_nonce(Nonce)),
|
|
203
|
+
NCBefore is Now - 60,
|
|
204
|
+
forall(nonce(Nonce, _Created),
|
|
205
|
+
gc_nonce_nc(Nonce, NCBefore)).
|
|
206
|
+
|
|
207
|
+
nonce_timed_out(Nonce, Before) :-
|
|
208
|
+
nonce(Nonce, Created),
|
|
209
|
+
Created < Before.
|
|
210
|
+
|
|
211
|
+
gc_nonce_nc(Nonce, Before) :-
|
|
212
|
+
findall(NC, gc_nonce_nc(Nonce, Before, NC), List),
|
|
213
|
+
sort(0, @>, List, [Max|_]),
|
|
214
|
+
!,
|
|
215
|
+
asserta(nonce_nc_first(Nonce, Max)),
|
|
216
|
+
forall(( nonce_nc_first(Nonce, NC),
|
|
217
|
+
NC \== Max
|
|
218
|
+
),
|
|
219
|
+
retractall(nonce_nc_first(Nonce, NC))).
|
|
220
|
+
gc_nonce_nc(_, _).
|
|
221
|
+
|
|
222
|
+
gc_nonce_nc(Nonce, Before, NC) :-
|
|
223
|
+
nonce_nc(Nonce, NC, Time),
|
|
224
|
+
Time < Before,
|
|
225
|
+
retractall(nonce_nc(Nonce, NC, Time)).
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
%! private_key(-PrivateKey) is det.
|
|
230
|
+
%
|
|
231
|
+
% Return our private key.
|
|
232
|
+
|
|
233
|
+
private_key(PrivateKey) :-
|
|
234
|
+
nonce_key(PrivateKey),
|
|
235
|
+
!.
|
|
236
|
+
private_key(PrivateKey) :-
|
|
237
|
+
with_mutex(http_digest,
|
|
238
|
+
private_key_sync(PrivateKey)).
|
|
239
|
+
|
|
240
|
+
private_key_sync(PrivateKey) :-
|
|
241
|
+
nonce_key(PrivateKey),
|
|
242
|
+
!.
|
|
243
|
+
private_key_sync(PrivateKey) :-
|
|
244
|
+
PrivateKey is random(1<<63-1),
|
|
245
|
+
assertz(nonce_key(PrivateKey)).
|
|
246
|
+
|
|
247
|
+
%! our_nonce(+Nonce, -Stamp:string) is semidet.
|
|
248
|
+
%
|
|
249
|
+
% True if we created Nonce at time Stamp.
|
|
250
|
+
%
|
|
251
|
+
% @arg Stamp is the stamp as created by nonce//1: a time
|
|
252
|
+
% stamp*1000+sequence number.
|
|
253
|
+
|
|
254
|
+
our_nonce(Nonce64, Stamp) :-
|
|
255
|
+
base64(Nonce, Nonce64),
|
|
256
|
+
split_string(Nonce, ":", "", [Stamp,HNonceContent]),
|
|
257
|
+
private_key(PrivateKey),
|
|
258
|
+
atomics_to_string([Stamp,PrivateKey], ":", NonceContent),
|
|
259
|
+
hash(NonceContent, HNonceContent).
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
/*******************************
|
|
263
|
+
* GRAMMAR *
|
|
264
|
+
*******************************/
|
|
265
|
+
|
|
266
|
+
%! http_digest_challenge(+Realm, +Options)//
|
|
267
|
+
%
|
|
268
|
+
% Generate the content for a 401 =|WWW-Authenticate: Digest|=
|
|
269
|
+
% header field.
|
|
270
|
+
|
|
271
|
+
http_digest_challenge(Realm, Options) -->
|
|
272
|
+
% "Digest ",
|
|
273
|
+
realm(Realm),
|
|
274
|
+
domain(Options),
|
|
275
|
+
nonce(Options),
|
|
276
|
+
option_value(opaque, Options),
|
|
277
|
+
stale(Options),
|
|
278
|
+
% algorithm(Options),
|
|
279
|
+
qop_options(Options).
|
|
280
|
+
% auth_param(Options).
|
|
281
|
+
|
|
282
|
+
realm(Realm) -->
|
|
283
|
+
{ no_dquote(realm, Realm) },
|
|
284
|
+
"realm=\"", atom(Realm), "\"".
|
|
285
|
+
|
|
286
|
+
domain(Options) -->
|
|
287
|
+
{ option(domain(Domain), Options) },
|
|
288
|
+
!,
|
|
289
|
+
sep, "domain=\"", uris(Domain), "\"".
|
|
290
|
+
domain(_) --> "".
|
|
291
|
+
|
|
292
|
+
uris(Domain) -->
|
|
293
|
+
{ atomic(Domain) },
|
|
294
|
+
!,
|
|
295
|
+
uri(Domain).
|
|
296
|
+
uris(Domains) -->
|
|
297
|
+
{ must_be(list(atomic), Domains)
|
|
298
|
+
},
|
|
299
|
+
uri_list(Domains).
|
|
300
|
+
|
|
301
|
+
uri_list([]) --> "".
|
|
302
|
+
uri_list([H|T]) -->
|
|
303
|
+
uri(H),
|
|
304
|
+
( {T \== []}
|
|
305
|
+
-> " ", uri_list(T)
|
|
306
|
+
; ""
|
|
307
|
+
).
|
|
308
|
+
|
|
309
|
+
uri(URI) -->
|
|
310
|
+
{ no_dquote(uri, URI) },
|
|
311
|
+
atom(URI).
|
|
312
|
+
|
|
313
|
+
%! nonce(+Options)
|
|
314
|
+
%
|
|
315
|
+
% Compute the server _nonce_ value. Note that we should never
|
|
316
|
+
% generate the same nonce twice for the same client. The client
|
|
317
|
+
% _may_ issue multiple requests without an authorization header
|
|
318
|
+
% for resources appearing on a page. As long as we return distinct
|
|
319
|
+
% nonce values, this is ok. If we do not, the server will reuse NC
|
|
320
|
+
% counters on the same nonce, which will break the authentication.
|
|
321
|
+
|
|
322
|
+
nonce(Options) -->
|
|
323
|
+
{ get_time(Now),
|
|
324
|
+
flag(http_digest_nonce_seq, Seq, Seq+1),
|
|
325
|
+
Stamp is floor(Now)*1000+(Seq mod 1000),
|
|
326
|
+
private_key(PrivateKey),
|
|
327
|
+
atomics_to_string([Stamp,PrivateKey], ":", NonceContent),
|
|
328
|
+
hash(NonceContent, HNonceContent),
|
|
329
|
+
atomics_to_string([Stamp,HNonceContent], ":", NonceText),
|
|
330
|
+
base64(NonceText, Nonce),
|
|
331
|
+
option(nonce(Nonce-Now), Options, _),
|
|
332
|
+
debug(http(authenticate), 'Server nonce: ~q', [Nonce])
|
|
333
|
+
},
|
|
334
|
+
sep, "nonce=\"", atom(Nonce), "\"".
|
|
335
|
+
|
|
336
|
+
stale(Options) -->
|
|
337
|
+
{ option(stale(true), Options), !
|
|
338
|
+
},
|
|
339
|
+
sep, "stale=true".
|
|
340
|
+
stale(_) --> "".
|
|
341
|
+
|
|
342
|
+
qop_options(_Options) -->
|
|
343
|
+
sep, "qop=\"auth,auth-int\"".
|
|
344
|
+
|
|
345
|
+
option_value(Key, Options) -->
|
|
346
|
+
{ Opt =.. [Key,Value],
|
|
347
|
+
option(Opt, Options), !
|
|
348
|
+
},
|
|
349
|
+
key_qvalue(Key, Value).
|
|
350
|
+
option_value(_, _) --> "".
|
|
351
|
+
|
|
352
|
+
key_value(Key, Value) -->
|
|
353
|
+
atom(Key), "=", atom(Value).
|
|
354
|
+
key_qvalue(Key, Value) -->
|
|
355
|
+
{ no_dquote(Key, Value) },
|
|
356
|
+
atom(Key), "=\"", atom(Value), "\"".
|
|
357
|
+
|
|
358
|
+
no_dquote(Key, Value) :-
|
|
359
|
+
nonvar(Value),
|
|
360
|
+
sub_atom(Value, _, _, _, '"'),
|
|
361
|
+
!,
|
|
362
|
+
domain_error(Key, value).
|
|
363
|
+
no_dquote(_, _).
|
|
364
|
+
|
|
365
|
+
sep --> ", ".
|
|
366
|
+
|
|
367
|
+
hash(Text, Hash) :-
|
|
368
|
+
md5_hash(Text, Hash, []).
|
|
369
|
+
|
|
370
|
+
%! http_digest_authenticate(+Request, -User, -UserFields, +Options)
|
|
371
|
+
%
|
|
372
|
+
% Validate the client response from the Request header. On success,
|
|
373
|
+
% User is the validated user and UserFields are additional fields
|
|
374
|
+
% from the password file. Options include:
|
|
375
|
+
%
|
|
376
|
+
% - passwd_file(+File)
|
|
377
|
+
% Validate passwords against the given password file. The
|
|
378
|
+
% file is read using http_current_user/3 from
|
|
379
|
+
% library(http/http_authenticate).
|
|
380
|
+
% - stale(-Stale)
|
|
381
|
+
% The request may succeed on a timed-out server nonce. In
|
|
382
|
+
% that case, Stale is unified with `true`.
|
|
383
|
+
|
|
384
|
+
http_digest_authenticate(Request, [User|Fields], Options) :-
|
|
385
|
+
memberchk(authorization(Authorization), Request),
|
|
386
|
+
debug(http(authenticate), 'Authorization: ~w', [Authorization]),
|
|
387
|
+
digest_authenticate(Authorization, User, Fields, Options).
|
|
388
|
+
|
|
389
|
+
digest_authenticate(Authorization, User, Fields, Options) :-
|
|
390
|
+
string_codes(Authorization, AuthorizationCodes),
|
|
391
|
+
phrase(parse_digest_reponse(AuthValues), AuthorizationCodes),
|
|
392
|
+
memberchk(username(User), AuthValues),
|
|
393
|
+
memberchk(realm(Realm), AuthValues),
|
|
394
|
+
memberchk(nonce(ServerNonce), AuthValues),
|
|
395
|
+
memberchk(uri(Path), AuthValues),
|
|
396
|
+
memberchk(qop(QOP), AuthValues),
|
|
397
|
+
memberchk(nc(NC), AuthValues),
|
|
398
|
+
memberchk(cnonce(ClientNonce), AuthValues),
|
|
399
|
+
memberchk(response(Response), AuthValues),
|
|
400
|
+
user_ha1_details(User, Realm, HA1, Fields, Options),
|
|
401
|
+
option(method(Method), Options, get),
|
|
402
|
+
ha2(Method, Path, HA2),
|
|
403
|
+
atomics_to_string([ HA1,
|
|
404
|
+
ServerNonce,
|
|
405
|
+
NC,
|
|
406
|
+
ClientNonce,
|
|
407
|
+
QOP,
|
|
408
|
+
HA2
|
|
409
|
+
], ":", ResponseText),
|
|
410
|
+
debug(http(authenticate), 'ResponseText: ~w', [ResponseText]),
|
|
411
|
+
hash(ResponseText, ResponseExpected),
|
|
412
|
+
( Response == ResponseExpected
|
|
413
|
+
-> debug(http(authenticate), 'We have a match!', [])
|
|
414
|
+
; debug(http(authenticate),
|
|
415
|
+
'~q \\== ~q', [Response, ResponseExpected]),
|
|
416
|
+
fail
|
|
417
|
+
),
|
|
418
|
+
nonce_ok(ServerNonce, NC, Stale),
|
|
419
|
+
( option(stale(Stale), Options)
|
|
420
|
+
-> true
|
|
421
|
+
; Stale == false
|
|
422
|
+
).
|
|
423
|
+
|
|
424
|
+
user_ha1_details(User, _Realm, HA1, Fields, Options) :-
|
|
425
|
+
option(passwd_file(File), Options),
|
|
426
|
+
http_current_user(File, User, [HA1|Fields]).
|
|
427
|
+
|
|
428
|
+
%! parse_digest_request(-Fields)//
|
|
429
|
+
%
|
|
430
|
+
% Parse a digest request into a list of Name(Value) terms.
|
|
431
|
+
|
|
432
|
+
parse_digest_request(Fields) -->
|
|
433
|
+
"Digest", whites,
|
|
434
|
+
digest_values(Fields).
|
|
435
|
+
|
|
436
|
+
%! parse_digest_reponse(-ResponseValues)//
|
|
437
|
+
|
|
438
|
+
parse_digest_reponse(ResponseValues) -->
|
|
439
|
+
"Digest", whites,
|
|
440
|
+
digest_values(ResponseValues).
|
|
441
|
+
|
|
442
|
+
|
|
443
|
+
digest_values([H|T]) -->
|
|
444
|
+
digest_value(H),
|
|
445
|
+
!,
|
|
446
|
+
whites,
|
|
447
|
+
( ","
|
|
448
|
+
-> whites,
|
|
449
|
+
digest_values(T)
|
|
450
|
+
; {T = []}
|
|
451
|
+
).
|
|
452
|
+
|
|
453
|
+
digest_value(V) -->
|
|
454
|
+
string_without(`=`, NameCodes), "=",
|
|
455
|
+
{ atom_codes(Name, NameCodes) },
|
|
456
|
+
digest_value(Name, V).
|
|
457
|
+
|
|
458
|
+
digest_value(Name, V) -->
|
|
459
|
+
"\"",
|
|
460
|
+
!,
|
|
461
|
+
string_without(`"`, ValueCodes), "\"",
|
|
462
|
+
{ parse_value(Name, ValueCodes, Value),
|
|
463
|
+
V =.. [Name,Value]
|
|
464
|
+
}.
|
|
465
|
+
digest_value(stale, stale(V)) -->
|
|
466
|
+
!,
|
|
467
|
+
boolean(V).
|
|
468
|
+
digest_value(Name, V) -->
|
|
469
|
+
string_without(`, `, ValueCodes),
|
|
470
|
+
{ parse_value(Name, ValueCodes, Value),
|
|
471
|
+
V =.. [Name,Value]
|
|
472
|
+
}.
|
|
473
|
+
|
|
474
|
+
|
|
475
|
+
parse_value(domain, Codes, Domain) :-
|
|
476
|
+
!,
|
|
477
|
+
string_codes(String, Codes),
|
|
478
|
+
atomic_list_concat(Domain, ' ', String).
|
|
479
|
+
parse_value(Name, Codes, Value) :-
|
|
480
|
+
atom_value(Name),
|
|
481
|
+
atom_codes(Value, Codes).
|
|
482
|
+
parse_value(_Name, Codes, Value) :-
|
|
483
|
+
string_codes(Value, Codes).
|
|
484
|
+
|
|
485
|
+
atom_value(realm).
|
|
486
|
+
atom_value(username).
|
|
487
|
+
atom_value(response).
|
|
488
|
+
atom_value(nonce).
|
|
489
|
+
atom_value(stale). % for misbehaving servers that quote stale
|
|
490
|
+
|
|
491
|
+
boolean(true) --> "true".
|
|
492
|
+
boolean(false) --> "false".
|
|
493
|
+
|
|
494
|
+
|
|
495
|
+
/*******************************
|
|
496
|
+
* CLIENT *
|
|
497
|
+
*******************************/
|
|
498
|
+
|
|
499
|
+
%! http_parse_digest_challenge(+Challenge, -Fields) is det.
|
|
500
|
+
%
|
|
501
|
+
% Parse the value of an HTTP =|WWW-Authenticate|= header into
|
|
502
|
+
% a list of Name(Value) terms.
|
|
503
|
+
|
|
504
|
+
http_parse_digest_challenge(Challenge, Fields) :-
|
|
505
|
+
string_codes(Challenge, ReqCodes),
|
|
506
|
+
phrase(parse_digest_request(Fields), ReqCodes).
|
|
507
|
+
|
|
508
|
+
%! http_digest_response(+Challenge, +User, +Password, -Reply, +Options)
|
|
509
|
+
%
|
|
510
|
+
% Formulate a reply to a digest authentication request. Options:
|
|
511
|
+
%
|
|
512
|
+
% - path(+Path)
|
|
513
|
+
% The request URI send along with the authentication. Defaults
|
|
514
|
+
% to `/`
|
|
515
|
+
% - method(+Method)
|
|
516
|
+
% The HTTP method. Defaults to `'GET'`
|
|
517
|
+
% - nc(+Integer)
|
|
518
|
+
% The nonce-count as an integer. This is formatted as an
|
|
519
|
+
% 8 hex-digit string.
|
|
520
|
+
%
|
|
521
|
+
% @arg Challenge is a list Name(Value), normally from
|
|
522
|
+
% http_parse_digest_challenge/2. Must contain
|
|
523
|
+
% `realm` and `nonce`. Optionally contains
|
|
524
|
+
% `opaque`.
|
|
525
|
+
% @arg User is the user we want to authenticated
|
|
526
|
+
% @arg Password is the user's password
|
|
527
|
+
% @arg Options provides additional options
|
|
528
|
+
|
|
529
|
+
http_digest_response(Fields, User, Password, Reply, Options) :-
|
|
530
|
+
phrase(http_digest_response(Fields, User, Password, Options), Codes),
|
|
531
|
+
string_codes(Reply, Codes).
|
|
532
|
+
|
|
533
|
+
http_digest_response(Fields, User, Password, Options) -->
|
|
534
|
+
{ memberchk(nonce(ServerNonce), Fields),
|
|
535
|
+
memberchk(realm(Realm), Fields),
|
|
536
|
+
client_nonce(ClientNonce),
|
|
537
|
+
http_digest_password_hash(User, Realm, Password, HA1),
|
|
538
|
+
QOP = 'auth',
|
|
539
|
+
option(path(Path), Options, /),
|
|
540
|
+
option(method(Method), Options, 'GET'),
|
|
541
|
+
option(nc(NC), Options, 1),
|
|
542
|
+
format(string(NCS), '~`0t~16r~8+', [NC]),
|
|
543
|
+
ha2(Method, Path, HA2),
|
|
544
|
+
atomics_to_string([ HA1,
|
|
545
|
+
ServerNonce,
|
|
546
|
+
NCS,
|
|
547
|
+
ClientNonce,
|
|
548
|
+
QOP,
|
|
549
|
+
HA2
|
|
550
|
+
], ":", ResponseText),
|
|
551
|
+
hash(ResponseText, Response)
|
|
552
|
+
},
|
|
553
|
+
"Digest ",
|
|
554
|
+
key_qvalue(username, User),
|
|
555
|
+
sep, key_qvalue(realm, Realm),
|
|
556
|
+
sep, key_qvalue(nonce, ServerNonce),
|
|
557
|
+
sep, key_qvalue(uri, Path),
|
|
558
|
+
sep, key_value(qop, QOP),
|
|
559
|
+
sep, key_value(nc, NCS),
|
|
560
|
+
sep, key_qvalue(cnonce, ClientNonce),
|
|
561
|
+
sep, key_qvalue(response, Response),
|
|
562
|
+
( { memberchk(opaque(Opaque), Fields) }
|
|
563
|
+
-> sep, key_qvalue(opaque, Opaque)
|
|
564
|
+
; ""
|
|
565
|
+
).
|
|
566
|
+
|
|
567
|
+
client_nonce(Nonce) :-
|
|
568
|
+
V is random(1<<32),
|
|
569
|
+
format(string(Nonce), '~`0t~16r~8|', [V]).
|
|
570
|
+
|
|
571
|
+
ha2(Method, Path, HA2) :-
|
|
572
|
+
string_upper(Method, UMethod),
|
|
573
|
+
atomics_to_string([UMethod,Path], ":", A2),
|
|
574
|
+
hash(A2, HA2).
|
|
575
|
+
|
|
576
|
+
%! http_digest_password_hash(+User, +Realm, +Password, -Hash) is det.
|
|
577
|
+
%
|
|
578
|
+
% Compute the password hash for the HTTP password file. Note that
|
|
579
|
+
% the HTTP digest mechanism does allow us to use a seeded expensive
|
|
580
|
+
% arbitrary hash function. Instead, the hash is defined as the MD5
|
|
581
|
+
% of the following components:
|
|
582
|
+
%
|
|
583
|
+
% ==
|
|
584
|
+
% <user>:<realm>:<password>.
|
|
585
|
+
% ==
|
|
586
|
+
%
|
|
587
|
+
% The inexpensive MD5 algorithm makes the hash sensitive to brute
|
|
588
|
+
% force attacks while the lack of seeding make the hashes sensitive
|
|
589
|
+
% for _rainbow table_ attacks, although the value is somewhat limited
|
|
590
|
+
% because the _realm_ and _user_ are part of the hash.
|
|
591
|
+
|
|
592
|
+
http_digest_password_hash(User, Realm, Password, HA1) :-
|
|
593
|
+
atomics_to_string([User,Realm,Password], ":", A1),
|
|
594
|
+
hash(A1, HA1).
|
|
595
|
+
|
|
596
|
+
|
|
597
|
+
/*******************************
|
|
598
|
+
* PLUGIN FOR HTTP_DISPATCH *
|
|
599
|
+
*******************************/
|
|
600
|
+
|
|
601
|
+
:- multifile
|
|
602
|
+
http:authenticate/3.
|
|
603
|
+
|
|
604
|
+
%! http:authenticate(+Digest, +Request, -Fields)
|
|
605
|
+
%
|
|
606
|
+
% Plugin for library(http_dispatch) to perform basic HTTP
|
|
607
|
+
% authentication. Note that we keep the authentication details
|
|
608
|
+
% cached to avoid a `nonce-replay' error in the case that the
|
|
609
|
+
% application tries to verify multiple times.
|
|
610
|
+
%
|
|
611
|
+
% This predicate throws http_reply(authorise(digest(Digest)))
|
|
612
|
+
%
|
|
613
|
+
% @arg Digest is a term digest(File, Realm, Options)
|
|
614
|
+
% @arg Request is the HTTP request
|
|
615
|
+
% @arg Fields describes the authenticated user with the option
|
|
616
|
+
% user(User) and with the option user_details(Fields) if
|
|
617
|
+
% the password file contains additional fields after the
|
|
618
|
+
% user and password.
|
|
619
|
+
|
|
620
|
+
http:authenticate(digest(File, Realm), Request, Details) :-
|
|
621
|
+
http:authenticate(digest(File, Realm, []), Request, Details).
|
|
622
|
+
http:authenticate(digest(File, Realm, Options), Request, Details) :-
|
|
623
|
+
current_output(CGI),
|
|
624
|
+
cgi_property(CGI, id(Id)),
|
|
625
|
+
( nb_current('$http_digest_user', Id-Details)
|
|
626
|
+
-> true
|
|
627
|
+
; authenticate(digest(File, Realm, Options), Request, Details),
|
|
628
|
+
nb_setval('$http_digest_user', Id-Details)
|
|
629
|
+
).
|
|
630
|
+
|
|
631
|
+
authenticate(digest(File, Realm, Options), Request,
|
|
632
|
+
[ user(User)
|
|
633
|
+
| Details
|
|
634
|
+
]) :-
|
|
635
|
+
( option(method(Method), Request, get),
|
|
636
|
+
http_digest_authenticate(Request, [User|Fields],
|
|
637
|
+
[ passwd_file(File),
|
|
638
|
+
stale(Stale),
|
|
639
|
+
method(Method)
|
|
640
|
+
])
|
|
641
|
+
-> ( Stale == false
|
|
642
|
+
-> ( Fields == []
|
|
643
|
+
-> Details = []
|
|
644
|
+
; Details = [user_details(Fields)]
|
|
645
|
+
),
|
|
646
|
+
Ok = true
|
|
647
|
+
; true
|
|
648
|
+
)
|
|
649
|
+
; true
|
|
650
|
+
),
|
|
651
|
+
( Ok == true
|
|
652
|
+
-> true
|
|
653
|
+
; add_option(nonce(Nonce-Created), Options, Options1),
|
|
654
|
+
add_stale(Stale, Options1, Options2),
|
|
655
|
+
phrase(http_digest_challenge(Realm, Options2), DigestCodes),
|
|
656
|
+
string_codes(Digest, DigestCodes),
|
|
657
|
+
register_nonce(Nonce, Created),
|
|
658
|
+
throw(http_reply(authorise(digest(Digest))))
|
|
659
|
+
).
|
|
660
|
+
|
|
661
|
+
add_option(Option, Options0, _) :-
|
|
662
|
+
option(Option, Options0),
|
|
663
|
+
!.
|
|
664
|
+
add_option(Option, Options0, [Option|Options0]).
|
|
665
|
+
|
|
666
|
+
add_stale(Stale, Options0, Options) :-
|
|
667
|
+
Stale == true,
|
|
668
|
+
!,
|
|
669
|
+
Options = [stale(true)|Options0].
|
|
670
|
+
add_stale(_, Options, Options).
|
|
671
|
+
|
|
672
|
+
|
|
673
|
+
/*******************************
|
|
674
|
+
* PLUGIN FOT HTTP_OPEN *
|
|
675
|
+
*******************************/
|
|
676
|
+
|
|
677
|
+
:- multifile
|
|
678
|
+
http:authenticate_client/2.
|
|
679
|
+
:- dynamic
|
|
680
|
+
client_nonce/4, % Authority, Domains, Keep, Time
|
|
681
|
+
client_nonce_nc/3, % Nonce, Count, Time
|
|
682
|
+
client_nonce_gc_time/1. % Time
|
|
683
|
+
|
|
684
|
+
%! http:authenticate_client(+URL, +Action) is semidet.
|
|
685
|
+
%
|
|
686
|
+
% This hooks is called by http_open/3 with the following Action
|
|
687
|
+
% value:
|
|
688
|
+
%
|
|
689
|
+
% - send_auth_header(+AuthData, +Out, +Options)
|
|
690
|
+
% Called when sending the initial request. AuthData contains
|
|
691
|
+
% the value for the http_open/3 option authorization(AuthData)
|
|
692
|
+
% and Out is a stream on which to write additional HTTP headers.
|
|
693
|
+
% - auth_reponse(+Headers, +OptionsIn, -Options)
|
|
694
|
+
% Called if the server replies with a 401 code, challenging the
|
|
695
|
+
% client. Our implementation adds a
|
|
696
|
+
% request_header(authorization=Digest) header to Options, causing
|
|
697
|
+
% http_open/3 to retry the request with the additional option.
|
|
698
|
+
|
|
699
|
+
http:authenticate_client(URL, auth_reponse(Headers, OptionsIn, Options)) :-
|
|
700
|
+
debug(http(authenticate), "Got 401 with ~p", [Headers]),
|
|
701
|
+
memberchk(www_authenticate(Authenticate), Headers),
|
|
702
|
+
http_parse_digest_challenge(Authenticate, Fields),
|
|
703
|
+
user_password(OptionsIn, User, Password),
|
|
704
|
+
!,
|
|
705
|
+
uri_components(URL, Components),
|
|
706
|
+
uri_data(path, Components, Path),
|
|
707
|
+
http_digest_response(Fields, User, Password, Digest,
|
|
708
|
+
[ path(Path)
|
|
709
|
+
| OptionsIn
|
|
710
|
+
]),
|
|
711
|
+
merge_options([ request_header(authorization=Digest)
|
|
712
|
+
],
|
|
713
|
+
OptionsIn, Options),
|
|
714
|
+
keep_digest_credentials(URL, Fields).
|
|
715
|
+
http:authenticate_client(URL, send_auth_header(Auth, Out, Options)) :-
|
|
716
|
+
authorization_data(Auth, User, Password),
|
|
717
|
+
uri_components(URL, Components),
|
|
718
|
+
uri_data(authority, Components, Authority),
|
|
719
|
+
uri_data(path, Components, Path),
|
|
720
|
+
digest_credentials(Authority, Path, Nonce, Fields),
|
|
721
|
+
!,
|
|
722
|
+
next_nonce_count(Nonce, NC),
|
|
723
|
+
debug(http(authenticate), "Continue ~p nc=~q", [URL, NC]),
|
|
724
|
+
http_digest_response(Fields, User, Password, Digest,
|
|
725
|
+
[ nc(NC),
|
|
726
|
+
path(Path)
|
|
727
|
+
| Options
|
|
728
|
+
]),
|
|
729
|
+
format(Out, 'Authorization: ~w\r\n', [Digest]).
|
|
730
|
+
http:authenticate_client(URL, send_auth_header(Auth, _Out, _Options)) :-
|
|
731
|
+
debug(http(authenticate), "Failed ~p", [URL]),
|
|
732
|
+
authorization_data(Auth, _User, _Password).
|
|
733
|
+
|
|
734
|
+
|
|
735
|
+
user_password(Options, User, Password) :-
|
|
736
|
+
option(authorization(Auth), Options),
|
|
737
|
+
authorization_data(Auth, User, Password).
|
|
738
|
+
|
|
739
|
+
authorization_data(digest(User, Password), User, Password).
|
|
740
|
+
|
|
741
|
+
%! digest_credentials(+Authority, +Path, -Nonce, -Fields) is semidet.
|
|
742
|
+
%
|
|
743
|
+
% True if we have digest credentials for Authority on Path with the
|
|
744
|
+
% server _nonce_ Nonce and additional Fields.
|
|
745
|
+
|
|
746
|
+
digest_credentials(Authority, Path, Nonce, Fields) :-
|
|
747
|
+
client_nonce(Authority, Domains, Fields, _Created),
|
|
748
|
+
in_domain(Path, Domains),
|
|
749
|
+
memberchk(nonce(Nonce), Fields),
|
|
750
|
+
!.
|
|
751
|
+
|
|
752
|
+
in_domain(Path, Domains) :-
|
|
753
|
+
member(Domain, Domains),
|
|
754
|
+
sub_atom(Path, 0, _, _, Domain),
|
|
755
|
+
!.
|
|
756
|
+
|
|
757
|
+
next_nonce_count(Nonce, NC) :-
|
|
758
|
+
with_mutex(http_digest_client,
|
|
759
|
+
next_nonce_count_sync(Nonce, NC)).
|
|
760
|
+
|
|
761
|
+
next_nonce_count_sync(Nonce, NC) :-
|
|
762
|
+
retract(client_nonce_nc(Nonce, NC0, _)),
|
|
763
|
+
!,
|
|
764
|
+
NC1 is NC0+1,
|
|
765
|
+
get_time(Now),
|
|
766
|
+
assert(client_nonce_nc(Nonce, NC1, Now)),
|
|
767
|
+
NC = NC1.
|
|
768
|
+
next_nonce_count_sync(Nonce, 2) :-
|
|
769
|
+
get_time(Now),
|
|
770
|
+
assert(client_nonce_nc(Nonce, 2, Now)).
|
|
771
|
+
|
|
772
|
+
%! keep_digest_credentials(+URL, +Fields)
|
|
773
|
+
%
|
|
774
|
+
% Keep the digest credentials for subsequent connections.
|
|
775
|
+
|
|
776
|
+
keep_digest_credentials(URL, Fields) :-
|
|
777
|
+
get_time(Now),
|
|
778
|
+
uri_components(URL, Components),
|
|
779
|
+
uri_data(authority, Components, Authority),
|
|
780
|
+
include(keep_field, Fields, Keep),
|
|
781
|
+
( memberchk(domain(Domains), Fields)
|
|
782
|
+
-> true
|
|
783
|
+
; Domains = [/]
|
|
784
|
+
),
|
|
785
|
+
assertz(client_nonce(Authority, Domains, Keep, Now)),
|
|
786
|
+
gc_client_nonce.
|
|
787
|
+
|
|
788
|
+
keep_field(realm(_)).
|
|
789
|
+
keep_field(nonce(_)).
|
|
790
|
+
keep_field(opaque(_)).
|
|
791
|
+
|
|
792
|
+
gc_client_nonce :-
|
|
793
|
+
client_nonce_gc_time(Last),
|
|
794
|
+
get_time(Now),
|
|
795
|
+
setting(client_nonce_timeout, TimeOut),
|
|
796
|
+
Now-Last < TimeOut/4,
|
|
797
|
+
!.
|
|
798
|
+
gc_client_nonce :-
|
|
799
|
+
get_time(Now),
|
|
800
|
+
retractall(client_nonce_gc_time(_)),
|
|
801
|
+
asserta(client_nonce_gc_time(Now)),
|
|
802
|
+
setting(client_nonce_timeout, TimeOut),
|
|
803
|
+
Before is Now-TimeOut,
|
|
804
|
+
forall(client_nonce_expired(Nonce, Before),
|
|
805
|
+
forget_client_nonce(Nonce)).
|
|
806
|
+
|
|
807
|
+
client_nonce_expired(Nonce, Before) :-
|
|
808
|
+
client_nonce(_Authority, _Domains, Fields, Created),
|
|
809
|
+
Created < Before,
|
|
810
|
+
memberchk(nonce(Nonce), Fields),
|
|
811
|
+
\+ ( client_nonce_nc(Nonce, _, Last),
|
|
812
|
+
Last < Before
|
|
813
|
+
).
|
|
814
|
+
|
|
815
|
+
forget_client_nonce(Nonce) :-
|
|
816
|
+
client_nonce(_, _, Fields, Created),
|
|
817
|
+
memberchk(nonce(Nonce), Fields),
|
|
818
|
+
!,
|
|
819
|
+
retractall(client_nonce(_, _, Fields, Created)),
|
|
820
|
+
retractall(client_nonce_nc(Nonce, _, _)).
|