12
12
* GNU Lesser General Public License for more details.
13
13
*)
14
14
15
- type 'a t = Uuidm .t
15
+ type without_secret =
16
+ [ `auth
17
+ | `blob
18
+ | `Bond
19
+ | `Certificate
20
+ | `Cluster
21
+ | `Cluster_host
22
+ | `console
23
+ | `crashdump
24
+ | `data_source
25
+ | `Diagnostics
26
+ | `DR_task
27
+ | `event
28
+ | `Feature
29
+ | `generation
30
+ | `Generic
31
+ | `GPU_group
32
+ | `host
33
+ | `host_cpu
34
+ | `host_crashdump
35
+ | `host_metrics
36
+ | `host_patch
37
+ | `LVHD
38
+ | `message
39
+ | `network
40
+ | `network_sriov
41
+ | `Observer
42
+ | `PBD
43
+ | `PCI
44
+ | `PGPU
45
+ | `PIF
46
+ | `PIF_metrics
47
+ | `pool
48
+ | `pool_patch
49
+ | `pool_update
50
+ | `probe_result
51
+ | `PUSB
52
+ | `PVS_cache_storage
53
+ | `PVS_proxy
54
+ | `PVS_server
55
+ | `PVS_site
56
+ | `Repository
57
+ | `role
58
+ | `SDN_controller
59
+ | `secret
60
+ | `SM
61
+ | `SR
62
+ | `sr_stat
63
+ | `subject
64
+ | `task
65
+ | `tunnel
66
+ | `USB_group
67
+ | `user
68
+ | `VBD
69
+ | `VBD_metrics
70
+ | `VDI
71
+ | `vdi_nbd_server_info
72
+ | `VGPU
73
+ | `VGPU_type
74
+ | `VIF
75
+ | `VIF_metrics
76
+ | `VLAN
77
+ | `VM
78
+ | `VM_appliance
79
+ | `VM_group
80
+ | `VM_guest_metrics
81
+ | `VM_metrics
82
+ | `VMPP
83
+ | `VMSS
84
+ | `VTPM
85
+ | `VUSB ]
86
+
87
+ type secret = [`session ]
88
+
89
+ type not_secret = [without_secret | `session of [`use_make_uuid_rnd_instead ]]
90
+
91
+ type all = [without_secret | secret ]
92
+
93
+ type 'a t = Uuidm .t constraint 'a = [< all ]
16
94
17
95
let null = Uuidm. nil
18
96
@@ -38,34 +116,40 @@ let is_uuid str = match of_string str with None -> false | Some _ -> true
38
116
39
117
let dev_urandom = " /dev/urandom"
40
118
119
+ let dev_urandom_fd = Unix. openfile dev_urandom [Unix. O_RDONLY ] 0o640
120
+ (* we can't close this in at_exit, because Crowbar runs at_exit, and
121
+ it'll fail because this FD will then be closed
122
+ *)
123
+
41
124
let read_bytes dev n =
42
- let fd = Unix. openfile dev [Unix. O_RDONLY ] 0o640 in
43
- let finally body_f clean_f =
44
- try
45
- let ret = body_f () in
46
- clean_f () ; ret
47
- with e -> clean_f () ; raise e
48
- in
49
- finally
50
- (fun () ->
51
- let buf = Bytes. create n in
52
- let read = Unix. read fd buf 0 n in
53
- if read <> n then
54
- raise End_of_file
55
- else
56
- Bytes. to_string buf
57
- )
58
- (fun () -> Unix. close fd)
59
-
60
- let make_uuid_urnd () = of_bytes (read_bytes dev_urandom 16 ) |> Option. get
61
-
62
- (* Use the CSPRNG-backed urandom *)
63
- let make = make_uuid_urnd
125
+ let buf = Bytes. create n in
126
+ let read = Unix. read dev buf 0 n in
127
+ if read <> n then
128
+ raise End_of_file
129
+ else
130
+ Bytes. to_string buf
131
+
132
+ let make_uuid_urnd () = of_bytes (read_bytes dev_urandom_fd 16 ) |> Option. get
133
+
134
+ (* * Use non-CSPRNG by default, for CSPRNG see {!val:make_uuid_urnd} *)
135
+ let make_uuid_fast =
136
+ let uuid_state = Random.State. make_self_init () in
137
+ (* On OCaml 5 we could use Random.State.split instead,
138
+ and on OCaml 4 the mutex may not be strictly needed
139
+ *)
140
+ let m = Mutex. create () in
141
+ let finally () = Mutex. unlock m in
142
+ let gen = Uuidm. v4_gen uuid_state in
143
+ fun () -> Mutex. lock m ; Fun. protect ~finally gen
144
+
145
+ let make_default = ref make_uuid_urnd
146
+
147
+ let make () = ! make_default ()
64
148
65
149
type cookie = string
66
150
67
151
let make_cookie () =
68
- read_bytes dev_urandom 64
152
+ read_bytes dev_urandom_fd 64
69
153
|> String. to_seq
70
154
|> Seq. map (fun c -> Printf. sprintf " %1x" (int_of_char c))
71
155
|> List. of_seq
0 commit comments