package devkit
Development kit - general purpose library
Install
Dune Dependency
Authors
Maintainers
Sources
devkit-1.20240429.tbz
sha256=222f8ac131b1d970dab7eeb2714bfd6b9338b88b1082e6e01c136ae19e7eaef4
sha512=c9e6d93e3d21e5530c0f4d5baca51bf1f0a5d19248f8af7678d0665bb5cdf295d7aaaaa3e50eb2e44b8720e55097cc675af4dc8ec45acf9da39feb3eae1405d5
doc/src/devkit.core/digest_auth.ml.html
Source file digest_auth.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
open Printf open Prelude open Httpev_common type t = { mutable stamp : Time.t; mutable index : int; realm : string; user : string; password : string; } type digest_request = { name:string; crealm:string; nonce:string; uri:string; qop:[`Auth | `Authi | `Unknown]; nc:string; cnonce:string; response:string; opaque:string; } module Parse = struct (* awful *) let appendlst lst elem = lst := List.append !lst [elem] let appendstr str elem = str := ((!str) ^ elem) let lowparse elem curstr curlist = if elem = ',' then begin if (String.length !curstr) > 0 then begin appendlst curlist !curstr ; end; curstr:=""; end else if (elem <> ' ')&&(elem <> '"')&&(elem<>'\n')&&(elem<>'\r') then appendstr curstr (Char.escaped elem) let make_tuple a b = (a,b) let highparse str curlist = let first_equal = try String.index str '='with Not_found -> Exn.fail "symbol = not found in %s" str in appendlst curlist (make_tuple (String.sub str 0 first_equal) (String.sub str (first_equal+1) (String.length(str)-1-first_equal))) let digest_request_from_string s = if String.length s < 6 then Exn.fail "Digest string too short"; let s1 = String.sub s 0 6 in if String.lowercase_ascii s1 <> "digest" then Exn.fail "Authorization fail - non-digest trying to connect"; let str = String.sub s 6 ((String.length s) - 6) in let tmpstr = ref "" in let a = str^"," in let tmplist = ref [] in String.iter (fun a -> lowparse a tmpstr tmplist) a; let resultlist = ref [] in List.iter (fun a -> highparse a resultlist) !tmplist; let get k = try List.assoc k !resultlist with Not_found -> "" in { name = get "username"; crealm = get "realm"; nonce = get "nonce"; uri = get "uri"; qop = (match get "qop" with "auth" -> `Auth | "auth-int" -> `Authi | _ -> `Unknown); nc = get "nc"; cnonce = get "cnonce"; response = get "response"; opaque = get "opaque"; } let _string_from_digest_request p = let s = "Digest username=\""^p.name^"\", realm=\""^p.crealm^"\", nonce=\""^p.nonce^"\", uri=\""^p.uri^"\", qop=" in let a = match p.qop with | `Auth -> s^"auth" | `Authi -> s^"auth-int" | `Unknown -> s^"unknown" in let a2 = a^", nc="^p.nc^", cnonce=\""^p.cnonce^"\", response=\""^p.response^"\", opaque=\""^p.opaque^"\"" in a2 end (* Parse *) let md5_hex_string = Digest.(to_hex $ string) let hash l = md5_hex_string @@ String.concat ":" l let digest_opaque = md5_hex_string @@ Action.random_bytes 64 let init ~realm ~user ~password () = { realm; user; password; stamp = Time.now (); index = 1; } let check t req = if Time.now () -. t.stamp > 300. then begin t.stamp <- Time.now (); t.index <- t.index + 1; end; let nonce = hash [Unix.string_of_inet_addr @@ client_ip req; string_of_float t.stamp; string_of_int t.index] in try let dig = List.assoc "authorization" req.headers |> Parse.digest_request_from_string in match dig.nonce = nonce with | false -> raise Not_found | true -> (* Nonce is ok, checking another params *) let ha1 = hash [t.user; t.realm; t.password] in let ha2 = hash [show_method req.meth; dig.uri] in let response = match dig.qop with | `Authi |`Auth -> hash [ha1; dig.nonce; dig.nc; dig.cnonce; "auth"; ha2] | `Unknown -> hash [ha1; dig.nonce; ha2] in if dig.opaque <> digest_opaque || dig.response <> response then raise Not_found; `Ok with | _ -> let v = sprintf "Digest realm=\"%s\", qop=\"auth\", nonce=\"%s\", opaque=\"%s\"" t.realm nonce digest_opaque in `Unauthorized ("WWW-Authenticate", v)
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>