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.
Files changed (550) hide show
  1. package/README.md +29 -0
  2. package/bin/swipl +0 -0
  3. package/bin/swipl-win +0 -0
  4. package/build-manifest.json +70 -0
  5. package/lib/cmake/swipl/SWIPLConfig.cmake +21 -0
  6. package/lib/cmake/swipl/SWIPLConfigVersion.cmake +65 -0
  7. package/lib/cmake/swipl/SWIPLTargets-release.cmake +28 -0
  8. package/lib/cmake/swipl/SWIPLTargets.cmake +109 -0
  9. package/lib/swipl/ABI +1 -0
  10. package/lib/swipl/LICENSE +41 -0
  11. package/lib/swipl/README.md +116 -0
  12. package/lib/swipl/app/README.md +25 -0
  13. package/lib/swipl/app/app.pl +87 -0
  14. package/lib/swipl/app/pack.pl +350 -0
  15. package/lib/swipl/app/qlf.pl +521 -0
  16. package/lib/swipl/app/splfr.pl +177 -0
  17. package/lib/swipl/app/sys.pl +310 -0
  18. package/lib/swipl/bin/swipl.home +1 -0
  19. package/lib/swipl/boot/apply.pl +73 -0
  20. package/lib/swipl/boot/attvar.pl +344 -0
  21. package/lib/swipl/boot/autoload.pl +1226 -0
  22. package/lib/swipl/boot/bags.pl +283 -0
  23. package/lib/swipl/boot/dcg.pl +388 -0
  24. package/lib/swipl/boot/dicts.pl +193 -0
  25. package/lib/swipl/boot/dwim.pl +485 -0
  26. package/lib/swipl/boot/engines.pl +152 -0
  27. package/lib/swipl/boot/expand.pl +1628 -0
  28. package/lib/swipl/boot/gc.pl +65 -0
  29. package/lib/swipl/boot/history.pl +304 -0
  30. package/lib/swipl/boot/init.pl +4682 -0
  31. package/lib/swipl/boot/iri.pl +64 -0
  32. package/lib/swipl/boot/license.pl +390 -0
  33. package/lib/swipl/boot/load.pl +81 -0
  34. package/lib/swipl/boot/messages.pl +2521 -0
  35. package/lib/swipl/boot/packs.pl +306 -0
  36. package/lib/swipl/boot/predopts.pl +154 -0
  37. package/lib/swipl/boot/qlf.pl +141 -0
  38. package/lib/swipl/boot/rc.pl +263 -0
  39. package/lib/swipl/boot/syspred.pl +1634 -0
  40. package/lib/swipl/boot/tabling.pl +2321 -0
  41. package/lib/swipl/boot/threads.pl +42 -0
  42. package/lib/swipl/boot/toplevel.pl +2248 -0
  43. package/lib/swipl/boot/topvars.pl +261 -0
  44. package/lib/swipl/boot.prc +0 -0
  45. package/lib/swipl/cmake/swipl.cmake +131 -0
  46. package/lib/swipl/customize/README.md +23 -0
  47. package/lib/swipl/customize/edit +101 -0
  48. package/lib/swipl/customize/init.pl +164 -0
  49. package/lib/swipl/demo/README.md +33 -0
  50. package/lib/swipl/demo/likes.pl +44 -0
  51. package/lib/swipl/doc/packages/examples/chr/bool.chr +281 -0
  52. package/lib/swipl/doc/packages/examples/chr/chrdif.chr +87 -0
  53. package/lib/swipl/doc/packages/examples/chr/chrfreeze.chr +6 -0
  54. package/lib/swipl/doc/packages/examples/chr/family.chr +116 -0
  55. package/lib/swipl/doc/packages/examples/chr/fib.chr +24 -0
  56. package/lib/swipl/doc/packages/examples/chr/fibonacci.chr +31 -0
  57. package/lib/swipl/doc/packages/examples/chr/gcd.chr +28 -0
  58. package/lib/swipl/doc/packages/examples/chr/leq.chr +34 -0
  59. package/lib/swipl/doc/packages/examples/chr/listdom.chr +138 -0
  60. package/lib/swipl/doc/packages/examples/chr/primes.chr +29 -0
  61. package/lib/swipl/doc/packages/examples/http/README.md +98 -0
  62. package/lib/swipl/doc/packages/examples/http/calc.pl +92 -0
  63. package/lib/swipl/doc/packages/examples/http/demo_body.pl +232 -0
  64. package/lib/swipl/doc/packages/examples/http/demo_client.pl +165 -0
  65. package/lib/swipl/doc/packages/examples/http/demo_daemon.pl +38 -0
  66. package/lib/swipl/doc/packages/examples/http/demo_files.pl +50 -0
  67. package/lib/swipl/doc/packages/examples/http/demo_hello.pl +15 -0
  68. package/lib/swipl/doc/packages/examples/http/demo_login.pl +280 -0
  69. package/lib/swipl/doc/packages/examples/http/demo_openid.pl +177 -0
  70. package/lib/swipl/doc/packages/examples/http/demo_pwp.pl +20 -0
  71. package/lib/swipl/doc/packages/examples/http/demo_rest.pl +56 -0
  72. package/lib/swipl/doc/packages/examples/http/demo_threads.pl +52 -0
  73. package/lib/swipl/doc/packages/examples/http/linux-init-script +126 -0
  74. package/lib/swipl/doc/packages/examples/http/pwp/context.pwp +23 -0
  75. package/lib/swipl/doc/packages/examples/http/pwp/index.pwp +25 -0
  76. package/lib/swipl/doc/packages/examples/http/pwp/pwp1.pwp +12 -0
  77. package/lib/swipl/doc/packages/examples/http/pwp/pwp2.pwp +10 -0
  78. package/lib/swipl/doc/packages/examples/http/pwp/pwp3.pwp +25 -0
  79. package/lib/swipl/doc/packages/examples/http/pwp/pwp4.pwp +23 -0
  80. package/lib/swipl/doc/packages/examples/http/pwp/pwp5.pwp +11 -0
  81. package/lib/swipl/doc/packages/examples/http/pwp/pwp6.pwp +3 -0
  82. package/lib/swipl/doc/packages/examples/http/pwp/pwp7.pwp +3 -0
  83. package/lib/swipl/doc/packages/examples/http/pwp/pwp8.pwp +3 -0
  84. package/lib/swipl/doc/packages/examples/http/pwp/pwpdb.pl +12 -0
  85. package/lib/swipl/doc/packages/examples/http/systemd-script.service +18 -0
  86. package/lib/swipl/doc/packages/examples/http/upstart-script.conf +20 -0
  87. package/lib/swipl/doc/packages/examples/plunit/read.pl +17 -0
  88. package/lib/swipl/doc/packages/examples/plunit/simple.pl +33 -0
  89. package/lib/swipl/doc/packages/examples/ssl/client.pl +83 -0
  90. package/lib/swipl/doc/packages/examples/ssl/etc/README +52 -0
  91. package/lib/swipl/doc/packages/examples/ssl/etc/client/client-cert.p12 +0 -0
  92. package/lib/swipl/doc/packages/examples/ssl/etc/client/client-cert.pem +85 -0
  93. package/lib/swipl/doc/packages/examples/ssl/etc/client/client-key.pem +30 -0
  94. package/lib/swipl/doc/packages/examples/ssl/etc/demoCA/cacert.pem +82 -0
  95. package/lib/swipl/doc/packages/examples/ssl/etc/demoCA/careq.pem +18 -0
  96. package/lib/swipl/doc/packages/examples/ssl/etc/demoCA/crlnumber +1 -0
  97. package/lib/swipl/doc/packages/examples/ssl/etc/demoCA/index.txt +3 -0
  98. package/lib/swipl/doc/packages/examples/ssl/etc/demoCA/index.txt.attr +1 -0
  99. package/lib/swipl/doc/packages/examples/ssl/etc/demoCA/newcerts/9DC08797A0F63F7C.pem +85 -0
  100. package/lib/swipl/doc/packages/examples/ssl/etc/demoCA/newcerts/9DC08797A0F63F7D.pem +85 -0
  101. package/lib/swipl/doc/packages/examples/ssl/etc/demoCA/private/cakey.pem +30 -0
  102. package/lib/swipl/doc/packages/examples/ssl/etc/demoCA/serial +1 -0
  103. package/lib/swipl/doc/packages/examples/ssl/etc/server/server-cert.pem +85 -0
  104. package/lib/swipl/doc/packages/examples/ssl/etc/server/server-key.pem +30 -0
  105. package/lib/swipl/doc/packages/examples/ssl/https.pl +267 -0
  106. package/lib/swipl/doc/packages/examples/ssl/server.pl +106 -0
  107. package/lib/swipl/include/SWI-Prolog.h +1544 -0
  108. package/lib/swipl/include/SWI-Stream.h +537 -0
  109. package/lib/swipl/include/Yap/YapInterface.h +283 -0
  110. package/lib/swipl/include/sicstus/sicstus.h +452 -0
  111. package/lib/swipl/lib/x86_64-linux/cgi.so +0 -0
  112. package/lib/swipl/lib/x86_64-linux/crypt.so +0 -0
  113. package/lib/swipl/lib/x86_64-linux/crypto4pl.so +0 -0
  114. package/lib/swipl/lib/x86_64-linux/double_metaphone.so +0 -0
  115. package/lib/swipl/lib/x86_64-linux/files.so +0 -0
  116. package/lib/swipl/lib/x86_64-linux/hashstream.so +0 -0
  117. package/lib/swipl/lib/x86_64-linux/http_stream.so +0 -0
  118. package/lib/swipl/lib/x86_64-linux/isub.so +0 -0
  119. package/lib/swipl/lib/x86_64-linux/json.so +0 -0
  120. package/lib/swipl/lib/x86_64-linux/libswipl.so.10 +0 -0
  121. package/lib/swipl/lib/x86_64-linux/mallocinfo.so +0 -0
  122. package/lib/swipl/lib/x86_64-linux/md54pl.so +0 -0
  123. package/lib/swipl/lib/x86_64-linux/memfile.so +0 -0
  124. package/lib/swipl/lib/x86_64-linux/ntriples.so +0 -0
  125. package/lib/swipl/lib/x86_64-linux/pcre4pl.so +0 -0
  126. package/lib/swipl/lib/x86_64-linux/porter_stem.so +0 -0
  127. package/lib/swipl/lib/x86_64-linux/process.so +0 -0
  128. package/lib/swipl/lib/x86_64-linux/prolog_stream.so +0 -0
  129. package/lib/swipl/lib/x86_64-linux/rdf_db.so +0 -0
  130. package/lib/swipl/lib/x86_64-linux/readutil.so +0 -0
  131. package/lib/swipl/lib/x86_64-linux/rlimit.so +0 -0
  132. package/lib/swipl/lib/x86_64-linux/sched.so +0 -0
  133. package/lib/swipl/lib/x86_64-linux/sgml2pl.so +0 -0
  134. package/lib/swipl/lib/x86_64-linux/sha4pl.so +0 -0
  135. package/lib/swipl/lib/x86_64-linux/snowball.so +0 -0
  136. package/lib/swipl/lib/x86_64-linux/socket.so +0 -0
  137. package/lib/swipl/lib/x86_64-linux/ssl4pl.so +0 -0
  138. package/lib/swipl/lib/x86_64-linux/streaminfo.so +0 -0
  139. package/lib/swipl/lib/x86_64-linux/syslog.so +0 -0
  140. package/lib/swipl/lib/x86_64-linux/time.so +0 -0
  141. package/lib/swipl/lib/x86_64-linux/turtle.so +0 -0
  142. package/lib/swipl/lib/x86_64-linux/uid.so +0 -0
  143. package/lib/swipl/lib/x86_64-linux/unix.so +0 -0
  144. package/lib/swipl/lib/x86_64-linux/uri.so +0 -0
  145. package/lib/swipl/lib/x86_64-linux/websocket.so +0 -0
  146. package/lib/swipl/lib/x86_64-linux/zlib4pl.so +0 -0
  147. package/lib/swipl/library/INDEX.pl +1020 -0
  148. package/lib/swipl/library/aggregate.pl +755 -0
  149. package/lib/swipl/library/ansi_term.pl +653 -0
  150. package/lib/swipl/library/apply.pl +426 -0
  151. package/lib/swipl/library/apply_macros.pl +497 -0
  152. package/lib/swipl/library/arithmetic.pl +320 -0
  153. package/lib/swipl/library/assoc.pl +522 -0
  154. package/lib/swipl/library/atom.pl +169 -0
  155. package/lib/swipl/library/backcomp.pl +688 -0
  156. package/lib/swipl/library/base32.pl +291 -0
  157. package/lib/swipl/library/base64.pl +441 -0
  158. package/lib/swipl/library/broadcast.pl +161 -0
  159. package/lib/swipl/library/build/cmake.pl +137 -0
  160. package/lib/swipl/library/build/conan.pl +232 -0
  161. package/lib/swipl/library/build/make.pl +168 -0
  162. package/lib/swipl/library/build/tools.pl +825 -0
  163. package/lib/swipl/library/charsio.pl +195 -0
  164. package/lib/swipl/library/check.pl +1097 -0
  165. package/lib/swipl/library/check_installation.pl +912 -0
  166. package/lib/swipl/library/clp/INDEX.pl +157 -0
  167. package/lib/swipl/library/clp/bounds.pl +2036 -0
  168. package/lib/swipl/library/clp/clp_distinct.pl +263 -0
  169. package/lib/swipl/library/clp/clp_events.pl +92 -0
  170. package/lib/swipl/library/clp/clpb.pl +1896 -0
  171. package/lib/swipl/library/clp/clpfd.pl +7906 -0
  172. package/lib/swipl/library/clp/simplex.pl +1580 -0
  173. package/lib/swipl/library/codesio.pl +182 -0
  174. package/lib/swipl/library/coinduction.pl +183 -0
  175. package/lib/swipl/library/console_input.pl +289 -0
  176. package/lib/swipl/library/csv.pl +611 -0
  177. package/lib/swipl/library/ctypes.pl +161 -0
  178. package/lib/swipl/library/date.pl +370 -0
  179. package/lib/swipl/library/dcg/INDEX.pl +35 -0
  180. package/lib/swipl/library/dcg/basics.pl +514 -0
  181. package/lib/swipl/library/dcg/high_order.pl +227 -0
  182. package/lib/swipl/library/debug.pl +499 -0
  183. package/lib/swipl/library/dialect/bim.pl +186 -0
  184. package/lib/swipl/library/dialect/commons.pl +77 -0
  185. package/lib/swipl/library/dialect/eclipse/test_util_iso.pl +355 -0
  186. package/lib/swipl/library/dialect/hprolog/format.pl +44 -0
  187. package/lib/swipl/library/dialect/hprolog.pl +314 -0
  188. package/lib/swipl/library/dialect/ifprolog.pl +1317 -0
  189. package/lib/swipl/library/dialect/iso/iso_predicates.pl +277 -0
  190. package/lib/swipl/library/dialect/sicstus/README.TXT +1 -0
  191. package/lib/swipl/library/dialect/sicstus/arrays.pl +121 -0
  192. package/lib/swipl/library/dialect/sicstus/block.pl +278 -0
  193. package/lib/swipl/library/dialect/sicstus/lists.pl +167 -0
  194. package/lib/swipl/library/dialect/sicstus/ordsets.pl +52 -0
  195. package/lib/swipl/library/dialect/sicstus/sockets.pl +174 -0
  196. package/lib/swipl/library/dialect/sicstus/system.pl +262 -0
  197. package/lib/swipl/library/dialect/sicstus/terms.pl +57 -0
  198. package/lib/swipl/library/dialect/sicstus/timeout.pl +92 -0
  199. package/lib/swipl/library/dialect/sicstus.pl +582 -0
  200. package/lib/swipl/library/dialect/sicstus4/aggregate.pl +60 -0
  201. package/lib/swipl/library/dialect/sicstus4/between.pl +62 -0
  202. package/lib/swipl/library/dialect/sicstus4/clpfd.pl +75 -0
  203. package/lib/swipl/library/dialect/sicstus4/file_systems.pl +413 -0
  204. package/lib/swipl/library/dialect/sicstus4/lists.pl +274 -0
  205. package/lib/swipl/library/dialect/sicstus4/ordsets.pl +54 -0
  206. package/lib/swipl/library/dialect/sicstus4/samsort.pl +86 -0
  207. package/lib/swipl/library/dialect/sicstus4/sets.pl +124 -0
  208. package/lib/swipl/library/dialect/sicstus4/sockets.pl +164 -0
  209. package/lib/swipl/library/dialect/sicstus4/system.pl +80 -0
  210. package/lib/swipl/library/dialect/sicstus4/terms.pl +89 -0
  211. package/lib/swipl/library/dialect/sicstus4/timeout.pl +43 -0
  212. package/lib/swipl/library/dialect/sicstus4/types.pl +103 -0
  213. package/lib/swipl/library/dialect/sicstus4.pl +200 -0
  214. package/lib/swipl/library/dialect/swi/syspred_options.pl +250 -0
  215. package/lib/swipl/library/dialect/xsb/README.md +20 -0
  216. package/lib/swipl/library/dialect/xsb/basics.pl +318 -0
  217. package/lib/swipl/library/dialect/xsb/consult.pl +87 -0
  218. package/lib/swipl/library/dialect/xsb/curr_sym.pl +57 -0
  219. package/lib/swipl/library/dialect/xsb/error_handler.pl +111 -0
  220. package/lib/swipl/library/dialect/xsb/gensym.pl +53 -0
  221. package/lib/swipl/library/dialect/xsb/gpp.pl +138 -0
  222. package/lib/swipl/library/dialect/xsb/intern.pl +48 -0
  223. package/lib/swipl/library/dialect/xsb/lists.pl +47 -0
  224. package/lib/swipl/library/dialect/xsb/machine.pl +295 -0
  225. package/lib/swipl/library/dialect/xsb/ordsets.pl +53 -0
  226. package/lib/swipl/library/dialect/xsb/setof.pl +54 -0
  227. package/lib/swipl/library/dialect/xsb/source.pl +308 -0
  228. package/lib/swipl/library/dialect/xsb/standard.pl +169 -0
  229. package/lib/swipl/library/dialect/xsb/storage.pl +70 -0
  230. package/lib/swipl/library/dialect/xsb/string.pl +76 -0
  231. package/lib/swipl/library/dialect/xsb/thread.pl +62 -0
  232. package/lib/swipl/library/dialect/xsb/timed_call.pl +158 -0
  233. package/lib/swipl/library/dialect/xsb.pl +688 -0
  234. package/lib/swipl/library/dialect/yap/README.TXT +8 -0
  235. package/lib/swipl/library/dialect/yap.pl +283 -0
  236. package/lib/swipl/library/dialect.pl +123 -0
  237. package/lib/swipl/library/dicts.pl +399 -0
  238. package/lib/swipl/library/dif.pl +426 -0
  239. package/lib/swipl/library/edinburgh.pl +138 -0
  240. package/lib/swipl/library/edit.pl +783 -0
  241. package/lib/swipl/library/error.pl +495 -0
  242. package/lib/swipl/library/exceptions.pl +231 -0
  243. package/lib/swipl/library/explain.pl +543 -0
  244. package/lib/swipl/library/ext/RDF/INDEX.pl +25 -0
  245. package/lib/swipl/library/ext/RDF/rdf.pl +450 -0
  246. package/lib/swipl/library/ext/RDF/rdf_parser.pl +649 -0
  247. package/lib/swipl/library/ext/RDF/rdf_triple.pl +448 -0
  248. package/lib/swipl/library/ext/RDF/rdf_write.pl +701 -0
  249. package/lib/swipl/library/ext/RDF/rewrite_term.pl +177 -0
  250. package/lib/swipl/library/ext/chr/chr/a_star.pl +80 -0
  251. package/lib/swipl/library/ext/chr/chr/binomialheap.pl +142 -0
  252. package/lib/swipl/library/ext/chr/chr/builtins.pl +629 -0
  253. package/lib/swipl/library/ext/chr/chr/chr_compiler_errors.pl +179 -0
  254. package/lib/swipl/library/ext/chr/chr/chr_compiler_options.pl +382 -0
  255. package/lib/swipl/library/ext/chr/chr/chr_compiler_utility.pl +338 -0
  256. package/lib/swipl/library/ext/chr/chr/chr_debug.pl +59 -0
  257. package/lib/swipl/library/ext/chr/chr/chr_hashtable_store.pl +425 -0
  258. package/lib/swipl/library/ext/chr/chr/chr_integertable_store.pl +139 -0
  259. package/lib/swipl/library/ext/chr/chr/chr_messages.pl +176 -0
  260. package/lib/swipl/library/ext/chr/chr/chr_op.pl +53 -0
  261. package/lib/swipl/library/ext/chr/chr/chr_runtime.pl +1016 -0
  262. package/lib/swipl/library/ext/chr/chr/chr_translate.pl +25424 -0
  263. package/lib/swipl/library/ext/chr/chr/clean_code.pl +252 -0
  264. package/lib/swipl/library/ext/chr/chr/find.pl +78 -0
  265. package/lib/swipl/library/ext/chr/chr/guard_entailment.pl +19432 -0
  266. package/lib/swipl/library/ext/chr/chr/listmap.pl +108 -0
  267. package/lib/swipl/library/ext/chr/chr/pairlist.pl +78 -0
  268. package/lib/swipl/library/ext/chr/chr.pl +686 -0
  269. package/lib/swipl/library/ext/clib/INDEX.pl +158 -0
  270. package/lib/swipl/library/ext/clib/cgi.pl +86 -0
  271. package/lib/swipl/library/ext/clib/crypt.pl +44 -0
  272. package/lib/swipl/library/ext/clib/filesex.pl +644 -0
  273. package/lib/swipl/library/ext/clib/hash_stream.pl +119 -0
  274. package/lib/swipl/library/ext/clib/mallocinfo.pl +138 -0
  275. package/lib/swipl/library/ext/clib/md5.pl +68 -0
  276. package/lib/swipl/library/ext/clib/memfile.pl +61 -0
  277. package/lib/swipl/library/ext/clib/process.pl +573 -0
  278. package/lib/swipl/library/ext/clib/prolog_server.pl +157 -0
  279. package/lib/swipl/library/ext/clib/prolog_stream.pl +80 -0
  280. package/lib/swipl/library/ext/clib/rlimit.pl +54 -0
  281. package/lib/swipl/library/ext/clib/sched.pl +85 -0
  282. package/lib/swipl/library/ext/clib/sha.pl +162 -0
  283. package/lib/swipl/library/ext/clib/socket.pl +1102 -0
  284. package/lib/swipl/library/ext/clib/streaminfo.pl +103 -0
  285. package/lib/swipl/library/ext/clib/streampool.pl +136 -0
  286. package/lib/swipl/library/ext/clib/syslog.pl +180 -0
  287. package/lib/swipl/library/ext/clib/time.pl +194 -0
  288. package/lib/swipl/library/ext/clib/udp_broadcast.pl +975 -0
  289. package/lib/swipl/library/ext/clib/uid.pl +220 -0
  290. package/lib/swipl/library/ext/clib/unix.pl +317 -0
  291. package/lib/swipl/library/ext/clib/uri.pl +530 -0
  292. package/lib/swipl/library/ext/clib/uuid.pl +207 -0
  293. package/lib/swipl/library/ext/http/http/INDEX.pl +266 -0
  294. package/lib/swipl/library/ext/http/http/README.md +34 -0
  295. package/lib/swipl/library/ext/http/http/ax.pl +189 -0
  296. package/lib/swipl/library/ext/http/http/dcg_basics.pl +49 -0
  297. package/lib/swipl/library/ext/http/http/graphql.pl +1367 -0
  298. package/lib/swipl/library/ext/http/http/html_decl.pl +416 -0
  299. package/lib/swipl/library/ext/http/http/html_head.pl +654 -0
  300. package/lib/swipl/library/ext/http/http/html_quasiquotations.pl +120 -0
  301. package/lib/swipl/library/ext/http/http/html_write.pl +1425 -0
  302. package/lib/swipl/library/ext/http/http/htmx.pl +139 -0
  303. package/lib/swipl/library/ext/http/http/http_authenticate.pl +364 -0
  304. package/lib/swipl/library/ext/http/http/http_client.pl +412 -0
  305. package/lib/swipl/library/ext/http/http/http_cookie.pl +245 -0
  306. package/lib/swipl/library/ext/http/http/http_cors.pl +176 -0
  307. package/lib/swipl/library/ext/http/http/http_digest.pl +820 -0
  308. package/lib/swipl/library/ext/http/http/http_dirindex.pl +296 -0
  309. package/lib/swipl/library/ext/http/http/http_dispatch.pl +1552 -0
  310. package/lib/swipl/library/ext/http/http/http_dyn_workers.pl +214 -0
  311. package/lib/swipl/library/ext/http/http/http_error.pl +126 -0
  312. package/lib/swipl/library/ext/http/http/http_exception.pl +225 -0
  313. package/lib/swipl/library/ext/http/http/http_files.pl +163 -0
  314. package/lib/swipl/library/ext/http/http/http_header.pl +2820 -0
  315. package/lib/swipl/library/ext/http/http/http_hook.pl +106 -0
  316. package/lib/swipl/library/ext/http/http/http_host.pl +204 -0
  317. package/lib/swipl/library/ext/http/http/http_load.pl +113 -0
  318. package/lib/swipl/library/ext/http/http/http_log.pl +738 -0
  319. package/lib/swipl/library/ext/http/http/http_multipart_plugin.pl +232 -0
  320. package/lib/swipl/library/ext/http/http/http_open.pl +1821 -0
  321. package/lib/swipl/library/ext/http/http/http_openid.pl +1561 -0
  322. package/lib/swipl/library/ext/http/http/http_parameters.pl +504 -0
  323. package/lib/swipl/library/ext/http/http/http_path.pl +380 -0
  324. package/lib/swipl/library/ext/http/http/http_proxy.pl +80 -0
  325. package/lib/swipl/library/ext/http/http/http_pwp.pl +351 -0
  326. package/lib/swipl/library/ext/http/http/http_redis_plugin.pl +332 -0
  327. package/lib/swipl/library/ext/http/http/http_server.pl +105 -0
  328. package/lib/swipl/library/ext/http/http/http_server_files.pl +126 -0
  329. package/lib/swipl/library/ext/http/http/http_server_health.pl +186 -0
  330. package/lib/swipl/library/ext/http/http/http_session.pl +1040 -0
  331. package/lib/swipl/library/ext/http/http/http_sgml_plugin.pl +137 -0
  332. package/lib/swipl/library/ext/http/http/http_stream.pl +376 -0
  333. package/lib/swipl/library/ext/http/http/http_unix_daemon.pl +989 -0
  334. package/lib/swipl/library/ext/http/http/http_wrapper.pl +559 -0
  335. package/lib/swipl/library/ext/http/http/hub.pl +600 -0
  336. package/lib/swipl/library/ext/http/http/js_write.pl +461 -0
  337. package/lib/swipl/library/ext/http/http/mimepack.pl +224 -0
  338. package/lib/swipl/library/ext/http/http/mimetype.pl +276 -0
  339. package/lib/swipl/library/ext/http/http/term_html.pl +797 -0
  340. package/lib/swipl/library/ext/http/http/thread_httpd.pl +1181 -0
  341. package/lib/swipl/library/ext/http/http/web/css/dirindex.css +24 -0
  342. package/lib/swipl/library/ext/http/http/web/css/openid.css +57 -0
  343. package/lib/swipl/library/ext/http/http/web/icons/back.png +0 -0
  344. package/lib/swipl/library/ext/http/http/web/icons/c.png +0 -0
  345. package/lib/swipl/library/ext/http/http/web/icons/compressed.png +0 -0
  346. package/lib/swipl/library/ext/http/http/web/icons/folder.png +0 -0
  347. package/lib/swipl/library/ext/http/http/web/icons/generic.png +0 -0
  348. package/lib/swipl/library/ext/http/http/web/icons/layout.png +0 -0
  349. package/lib/swipl/library/ext/http/http/web/icons/openid-logo-square.png +0 -0
  350. package/lib/swipl/library/ext/http/http/web/icons/openid-logo-tiny.png +0 -0
  351. package/lib/swipl/library/ext/http/http/websocket.pl +729 -0
  352. package/lib/swipl/library/ext/http/http/yadis.pl +205 -0
  353. package/lib/swipl/library/ext/json/INDEX.pl +36 -0
  354. package/lib/swipl/library/ext/json/http/INDEX.pl +16 -0
  355. package/lib/swipl/library/ext/json/http/http_json.pl +490 -0
  356. package/lib/swipl/library/ext/json/http/js_grammar.pl +53 -0
  357. package/lib/swipl/library/ext/json/http/json.pl +48 -0
  358. package/lib/swipl/library/ext/json/http/json_convert.pl +48 -0
  359. package/lib/swipl/library/ext/json/json.pl +1215 -0
  360. package/lib/swipl/library/ext/json/json_convert.pl +681 -0
  361. package/lib/swipl/library/ext/json/json_grammar.pl +349 -0
  362. package/lib/swipl/library/ext/json/json_rpc_client.pl +423 -0
  363. package/lib/swipl/library/ext/json/json_rpc_common.pl +104 -0
  364. package/lib/swipl/library/ext/json/json_rpc_server.pl +489 -0
  365. package/lib/swipl/library/ext/json/json_schema.pl +2111 -0
  366. package/lib/swipl/library/ext/nlp/INDEX.pl +15 -0
  367. package/lib/swipl/library/ext/nlp/double_metaphone.pl +86 -0
  368. package/lib/swipl/library/ext/nlp/isub.pl +162 -0
  369. package/lib/swipl/library/ext/nlp/porter_stem.pl +50 -0
  370. package/lib/swipl/library/ext/nlp/snowball.pl +97 -0
  371. package/lib/swipl/library/ext/pcre/INDEX.pl +17 -0
  372. package/lib/swipl/library/ext/pcre/pcre.pl +974 -0
  373. package/lib/swipl/library/ext/plunit/INDEX.pl +20 -0
  374. package/lib/swipl/library/ext/plunit/plunit.pl +2631 -0
  375. package/lib/swipl/library/ext/plunit/test_wizard.pl +249 -0
  376. package/lib/swipl/library/ext/semweb/semweb/INDEX.pl +288 -0
  377. package/lib/swipl/library/ext/semweb/semweb/rdf11.pl +2106 -0
  378. package/lib/swipl/library/ext/semweb/semweb/rdf11_containers.pl +299 -0
  379. package/lib/swipl/library/ext/semweb/semweb/rdf_cache.pl +278 -0
  380. package/lib/swipl/library/ext/semweb/semweb/rdf_compare.pl +132 -0
  381. package/lib/swipl/library/ext/semweb/semweb/rdf_db.pl +3468 -0
  382. package/lib/swipl/library/ext/semweb/semweb/rdf_edit.pl +1145 -0
  383. package/lib/swipl/library/ext/semweb/semweb/rdf_http_plugin.pl +274 -0
  384. package/lib/swipl/library/ext/semweb/semweb/rdf_library.pl +1021 -0
  385. package/lib/swipl/library/ext/semweb/semweb/rdf_litindex.pl +1035 -0
  386. package/lib/swipl/library/ext/semweb/semweb/rdf_ntriples.pl +422 -0
  387. package/lib/swipl/library/ext/semweb/semweb/rdf_persistency.pl +1576 -0
  388. package/lib/swipl/library/ext/semweb/semweb/rdf_portray.pl +182 -0
  389. package/lib/swipl/library/ext/semweb/semweb/rdf_prefixes.pl +681 -0
  390. package/lib/swipl/library/ext/semweb/semweb/rdf_sandbox.pl +153 -0
  391. package/lib/swipl/library/ext/semweb/semweb/rdf_turtle.pl +54 -0
  392. package/lib/swipl/library/ext/semweb/semweb/rdf_turtle_write.pl +1587 -0
  393. package/lib/swipl/library/ext/semweb/semweb/rdf_zlib_plugin.pl +52 -0
  394. package/lib/swipl/library/ext/semweb/semweb/rdfa.pl +1510 -0
  395. package/lib/swipl/library/ext/semweb/semweb/rdfs.pl +475 -0
  396. package/lib/swipl/library/ext/semweb/semweb/sparql_client.pl +643 -0
  397. package/lib/swipl/library/ext/semweb/semweb/turtle.pl +455 -0
  398. package/lib/swipl/library/ext/sgml/DTD/HTML4.dcl +88 -0
  399. package/lib/swipl/library/ext/sgml/DTD/HTML4.dtd +1092 -0
  400. package/lib/swipl/library/ext/sgml/DTD/HTML4.soc +6 -0
  401. package/lib/swipl/library/ext/sgml/DTD/HTML5.dtd +906 -0
  402. package/lib/swipl/library/ext/sgml/DTD/HTMLlat1.ent +195 -0
  403. package/lib/swipl/library/ext/sgml/DTD/HTMLspec.ent +77 -0
  404. package/lib/swipl/library/ext/sgml/DTD/HTMLsym.ent +241 -0
  405. package/lib/swipl/library/ext/sgml/INDEX.pl +64 -0
  406. package/lib/swipl/library/ext/sgml/c14n2.pl +203 -0
  407. package/lib/swipl/library/ext/sgml/iso_639.pl +631 -0
  408. package/lib/swipl/library/ext/sgml/pwp.pl +705 -0
  409. package/lib/swipl/library/ext/sgml/sgml.pl +815 -0
  410. package/lib/swipl/library/ext/sgml/sgml_write.pl +1003 -0
  411. package/lib/swipl/library/ext/sgml/xpath.pl +620 -0
  412. package/lib/swipl/library/ext/sgml/xsdp_types.pl +232 -0
  413. package/lib/swipl/library/ext/ssl/INDEX.pl +60 -0
  414. package/lib/swipl/library/ext/ssl/crypto.pl +1015 -0
  415. package/lib/swipl/library/ext/ssl/http/INDEX.pl +5 -0
  416. package/lib/swipl/library/ext/ssl/http/http_ssl_plugin.pl +296 -0
  417. package/lib/swipl/library/ext/ssl/saml.pl +609 -0
  418. package/lib/swipl/library/ext/ssl/ssl.pl +647 -0
  419. package/lib/swipl/library/ext/ssl/xmldsig.pl +391 -0
  420. package/lib/swipl/library/ext/ssl/xmlenc.pl +354 -0
  421. package/lib/swipl/library/ext/zlib/INDEX.pl +8 -0
  422. package/lib/swipl/library/ext/zlib/zlib.pl +112 -0
  423. package/lib/swipl/library/fastrw.pl +105 -0
  424. package/lib/swipl/library/files.pl +80 -0
  425. package/lib/swipl/library/gensym.pl +111 -0
  426. package/lib/swipl/library/git.pl +1027 -0
  427. package/lib/swipl/library/hashtable.pl +365 -0
  428. package/lib/swipl/library/heaps.pl +252 -0
  429. package/lib/swipl/library/hotfix.pl +239 -0
  430. package/lib/swipl/library/http/jquery.pl +103 -0
  431. package/lib/swipl/library/http/web/js/jquery-3.6.0.min.js +2 -0
  432. package/lib/swipl/library/increval.pl +217 -0
  433. package/lib/swipl/library/intercept.pl +263 -0
  434. package/lib/swipl/library/iostream.pl +237 -0
  435. package/lib/swipl/library/iri_scheme/file.pl +70 -0
  436. package/lib/swipl/library/lazy_lists.pl +481 -0
  437. package/lib/swipl/library/listing.pl +1362 -0
  438. package/lib/swipl/library/lists.pl +860 -0
  439. package/lib/swipl/library/lynx/INDEX.pl +14 -0
  440. package/lib/swipl/library/lynx/format.pl +380 -0
  441. package/lib/swipl/library/lynx/html_style.pl +129 -0
  442. package/lib/swipl/library/lynx/html_text.pl +865 -0
  443. package/lib/swipl/library/lynx/pldoc_style.pl +87 -0
  444. package/lib/swipl/library/macros.pl +451 -0
  445. package/lib/swipl/library/main.pl +1200 -0
  446. package/lib/swipl/library/make.pl +197 -0
  447. package/lib/swipl/library/modules.pl +129 -0
  448. package/lib/swipl/library/nb_rbtrees.pl +267 -0
  449. package/lib/swipl/library/nb_set.pl +203 -0
  450. package/lib/swipl/library/obfuscate.pl +115 -0
  451. package/lib/swipl/library/occurs.pl +241 -0
  452. package/lib/swipl/library/operators.pl +182 -0
  453. package/lib/swipl/library/option.pl +388 -0
  454. package/lib/swipl/library/optparse.pl +966 -0
  455. package/lib/swipl/library/ordsets.pl +518 -0
  456. package/lib/swipl/library/oset.pl +160 -0
  457. package/lib/swipl/library/pairs.pl +187 -0
  458. package/lib/swipl/library/persistency.pl +713 -0
  459. package/lib/swipl/library/pio.pl +47 -0
  460. package/lib/swipl/library/portray_text.pl +277 -0
  461. package/lib/swipl/library/pprint.pl +940 -0
  462. package/lib/swipl/library/predicate_options.pl +975 -0
  463. package/lib/swipl/library/prolog_autoload.pl +233 -0
  464. package/lib/swipl/library/prolog_breakpoints.pl +396 -0
  465. package/lib/swipl/library/prolog_clause.pl +1104 -0
  466. package/lib/swipl/library/prolog_code.pl +416 -0
  467. package/lib/swipl/library/prolog_codewalk.pl +1248 -0
  468. package/lib/swipl/library/prolog_colour.pl +3301 -0
  469. package/lib/swipl/library/prolog_colour.qlf +0 -0
  470. package/lib/swipl/library/prolog_config.pl +154 -0
  471. package/lib/swipl/library/prolog_coverage.pl +1333 -0
  472. package/lib/swipl/library/prolog_debug.pl +404 -0
  473. package/lib/swipl/library/prolog_deps.pl +675 -0
  474. package/lib/swipl/library/prolog_evaluable.pl +234 -0
  475. package/lib/swipl/library/prolog_format.pl +219 -0
  476. package/lib/swipl/library/prolog_history.pl +161 -0
  477. package/lib/swipl/library/prolog_jiti.pl +333 -0
  478. package/lib/swipl/library/prolog_locale.pl +61 -0
  479. package/lib/swipl/library/prolog_metainference.pl +307 -0
  480. package/lib/swipl/library/prolog_pack.pl +3906 -0
  481. package/lib/swipl/library/prolog_profile.pl +346 -0
  482. package/lib/swipl/library/prolog_qlfmake.pl +533 -0
  483. package/lib/swipl/library/prolog_source.pl +1188 -0
  484. package/lib/swipl/library/prolog_stack.pl +794 -0
  485. package/lib/swipl/library/prolog_trace.pl +365 -0
  486. package/lib/swipl/library/prolog_versions.pl +347 -0
  487. package/lib/swipl/library/prolog_wrap.pl +164 -0
  488. package/lib/swipl/library/prolog_xref.pl +3090 -0
  489. package/lib/swipl/library/prolog_xref.qlf +0 -0
  490. package/lib/swipl/library/pure_input.pl +266 -0
  491. package/lib/swipl/library/qpforeign.pl +695 -0
  492. package/lib/swipl/library/qsave.pl +1516 -0
  493. package/lib/swipl/library/quasi_quotations.pl +300 -0
  494. package/lib/swipl/library/quintus.pl +437 -0
  495. package/lib/swipl/library/random.pl +459 -0
  496. package/lib/swipl/library/rbtrees.pl +1153 -0
  497. package/lib/swipl/library/readln.pl +256 -0
  498. package/lib/swipl/library/readutil.pl +304 -0
  499. package/lib/swipl/library/record.pl +544 -0
  500. package/lib/swipl/library/rwlocks.pl +172 -0
  501. package/lib/swipl/library/sandbox.pl +1384 -0
  502. package/lib/swipl/library/semweb/dc.rdfs +198 -0
  503. package/lib/swipl/library/semweb/eor.rdfs +95 -0
  504. package/lib/swipl/library/semweb/owl.owl +287 -0
  505. package/lib/swipl/library/semweb/rdf_library.ttl +90 -0
  506. package/lib/swipl/library/semweb/rdfs.rdfs +251 -0
  507. package/lib/swipl/library/settings.pl +755 -0
  508. package/lib/swipl/library/shell.pl +462 -0
  509. package/lib/swipl/library/shlib.pl +670 -0
  510. package/lib/swipl/library/solution_sequences.pl +439 -0
  511. package/lib/swipl/library/sort.pl +119 -0
  512. package/lib/swipl/library/statistics.pl +541 -0
  513. package/lib/swipl/library/streams.pl +118 -0
  514. package/lib/swipl/library/strings.pl +469 -0
  515. package/lib/swipl/library/system.pl +95 -0
  516. package/lib/swipl/library/tables.pl +381 -0
  517. package/lib/swipl/library/tableutil.pl +771 -0
  518. package/lib/swipl/library/tabling.pl +42 -0
  519. package/lib/swipl/library/terms.pl +457 -0
  520. package/lib/swipl/library/theme/auto.pl +61 -0
  521. package/lib/swipl/library/theme/dark.pl +455 -0
  522. package/lib/swipl/library/theme/light.pl +45 -0
  523. package/lib/swipl/library/thread.pl +810 -0
  524. package/lib/swipl/library/thread_pool.pl +508 -0
  525. package/lib/swipl/library/threadutil.pl +574 -0
  526. package/lib/swipl/library/tty.pl +316 -0
  527. package/lib/swipl/library/ugraphs.pl +644 -0
  528. package/lib/swipl/library/unicode/INDEX.pl +6 -0
  529. package/lib/swipl/library/unicode/blocks.pl +414 -0
  530. package/lib/swipl/library/url.pl +1129 -0
  531. package/lib/swipl/library/utf8.pl +145 -0
  532. package/lib/swipl/library/varnumbers.pl +221 -0
  533. package/lib/swipl/library/vm.pl +251 -0
  534. package/lib/swipl/library/wfs.pl +205 -0
  535. package/lib/swipl/library/when.pl +263 -0
  536. package/lib/swipl/library/writef.pl +278 -0
  537. package/lib/swipl/library/www_browser.pl +251 -0
  538. package/lib/swipl/library/yall.pl +574 -0
  539. package/lib/swipl/library/zip.pl +211 -0
  540. package/lib/swipl/swipl.home +1 -0
  541. package/lib/vendor/libcrypto.so.3 +0 -0
  542. package/lib/vendor/libpcre2-8.so.0 +0 -0
  543. package/lib/vendor/libssl.so.3 +0 -0
  544. package/lib/vendor/libz.so.1 +0 -0
  545. package/licenses/OpenSSL-LICENSE.txt +177 -0
  546. package/licenses/PCRE2-COPYING +5 -0
  547. package/licenses/README.md +12 -0
  548. package/licenses/SWI-Prolog-LICENSE +41 -0
  549. package/licenses/zlib-LICENSE +22 -0
  550. 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, _, _)).