blob: 9e6dae8440cff518b02e929316853785b25d7b8b (
plain)
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
|
module F = Filename
(*type value_constraint = Regex of string | External of string * string option*)
type value_constraint =
| Regex of string [@name "regex"]
| External of string * string option [@name "exec"]
[@@deriving yojson]
exception Bad_validator of string
let validate_value dir buf value_constraint value =
match value_constraint with
| Regex s ->
(try
let _ = Pcre.exec ~pat:(Printf.sprintf "^%s$" s) value in true
with Not_found -> false)
| External (v, c) ->
(* XXX: Unix.open_process_in is "shelling out", which is a bad idea on multiple levels,
especially when the input comes directly from the user...
We should do something about it.
*)
let validator = F.concat dir v in
let cmd =
match c with
| Some arg ->
let safe_arg = Printf.sprintf "%s" (Pcre.qreplace ~pat:"\"" ~templ:"\\\"" arg) in
Printf.sprintf "%s %s \'%s\' 2>&1" validator safe_arg value
| None ->
Printf.sprintf "%s \'%s\' 2>&1" validator value
in
let () = Unix.putenv "vyos_libexec_dir" "/usr/libexec/vyos" in
let () = Unix.putenv "vyos_validators_dir" "/usr/libexec/vyos/validators" in
let chan = Unix.open_process_in cmd in
let out = try CCIO.read_all chan with _ -> "" in
let result = Unix.close_process_in chan in
match result with
| Unix.WEXITED 0 -> true
| Unix.WEXITED 127 ->
raise (Bad_validator (Printf.sprintf "Could not execute validator %s" validator))
| _ ->
let () = Buffer.add_string buf out in
false
(* If no constraints given, consider it valid.
Otherwise consider it valid if it satisfies at least one constraint *)
let validate_any validators constraints value =
let buf = Buffer.create 4096 in
let validate_exists validators constraints value =
match constraints with
| [] -> true
| _ ->
try
List.exists (fun c -> validate_value validators buf c value) constraints
with Bad_validator e -> let () = Buffer.add_string buf e in false
in
match validate_exists validators constraints value with
| true ->
let () = Buffer.clear buf in
None
| false ->
let out = Buffer.contents buf in
let () = Buffer.clear buf in
Some out
(* If no constraints given, consider it valid.
Otherwise consider it valid if it satisfies all constraints *)
let validate_all validators constraints value =
let buf = Buffer.create 4096 in
let validate_forall validators constraints value =
match constraints with
| [] -> true
| _ ->
try
List.for_all (fun c -> validate_value validators buf c value) constraints
with Bad_validator e -> let () = Buffer.add_string buf e in false
in
match validate_forall validators constraints value with
| true ->
let () = Buffer.clear buf in
None
| false ->
let out = Buffer.contents buf in
let () = Buffer.clear buf in
Some out
|