|
|
0d20ef |
From 322a146ddc69384255f0567a85e7db56a9e36454 Mon Sep 17 00:00:00 2001
|
|
|
0d20ef |
From: "Richard W.M. Jones" <rjones@redhat.com>
|
|
|
0d20ef |
Date: Thu, 30 Oct 2014 09:02:00 +0000
|
|
|
0d20ef |
Subject: [PATCH] v2v: vmware: Use 'curl --config' to pass arguments securely
|
|
|
0d20ef |
to curl.
|
|
|
0d20ef |
|
|
|
0d20ef |
Instead of making up an ordinary curl command line, write a temporary
|
|
|
0d20ef |
config file and use 'curl --config tmpfile' to pass the arguments.
|
|
|
0d20ef |
|
|
|
0d20ef |
The advantage is that it's more secure if we want to supply passwords
|
|
|
0d20ef |
to curl, since a '--user username:password' parameter on the command
|
|
|
0d20ef |
line could be read (eg. by 'ps ax'), but the temporary file has mode
|
|
|
0d20ef |
0600 and cannot be read by other users.
|
|
|
0d20ef |
|
|
|
0d20ef |
This is mostly code motion, but it also passes the '-q' option to curl
|
|
|
0d20ef |
to stop it from reading default configuration files.
|
|
|
0d20ef |
|
|
|
0d20ef |
(cherry picked from commit b35b84684c845ceefd3c0ec519caf80366a798ea)
|
|
|
0d20ef |
---
|
|
|
0d20ef |
v2v/input_libvirt_vcenter_https.ml | 75 +++++++++++++++++++++++++++++++++-----
|
|
|
0d20ef |
1 file changed, 65 insertions(+), 10 deletions(-)
|
|
|
0d20ef |
|
|
|
0d20ef |
diff --git a/v2v/input_libvirt_vcenter_https.ml b/v2v/input_libvirt_vcenter_https.ml
|
|
|
0d20ef |
index 56097e0..e514362 100644
|
|
|
0d20ef |
--- a/v2v/input_libvirt_vcenter_https.ml
|
|
|
0d20ef |
+++ b/v2v/input_libvirt_vcenter_https.ml
|
|
|
0d20ef |
@@ -36,23 +36,45 @@ let readahead_for_copying = Some (64 * 1024 * 1024)
|
|
|
0d20ef |
(* Return the session cookie. It is memoized, so you can call this
|
|
|
0d20ef |
* as often as required.
|
|
|
0d20ef |
*)
|
|
|
0d20ef |
-let get_session_cookie =
|
|
|
0d20ef |
+let rec get_session_cookie =
|
|
|
0d20ef |
let session_cookie = ref "" in
|
|
|
0d20ef |
fun verbose scheme uri sslverify url ->
|
|
|
0d20ef |
if !session_cookie <> "" then
|
|
|
0d20ef |
Some !session_cookie
|
|
|
0d20ef |
else (
|
|
|
0d20ef |
- let cmd =
|
|
|
0d20ef |
- sprintf "curl -s%s%s%s -I %s ||:"
|
|
|
0d20ef |
- (if not sslverify then " --insecure" else "")
|
|
|
0d20ef |
- (match uri.uri_user with Some _ -> " -u" | None -> "")
|
|
|
0d20ef |
- (match uri.uri_user with Some user -> " " ^ quote user | None -> "")
|
|
|
0d20ef |
- (quote url) in
|
|
|
0d20ef |
- let lines = external_command ~prog cmd in
|
|
|
0d20ef |
+ let curl_args = [
|
|
|
0d20ef |
+ "head", None;
|
|
|
0d20ef |
+ "silent", None;
|
|
|
0d20ef |
+ "url", Some url;
|
|
|
0d20ef |
+ ] in
|
|
|
0d20ef |
+ let curl_args =
|
|
|
0d20ef |
+ match uri.uri_user with
|
|
|
0d20ef |
+ | Some user -> ("user", Some user) :: curl_args
|
|
|
0d20ef |
+ | None -> curl_args in
|
|
|
0d20ef |
+ let curl_args =
|
|
|
0d20ef |
+ if not sslverify then ("insecure", None) :: curl_args else curl_args in
|
|
|
0d20ef |
+
|
|
|
0d20ef |
+ let lines = run_curl_get_lines curl_args in
|
|
|
0d20ef |
|
|
|
0d20ef |
let dump_response chan =
|
|
|
0d20ef |
- fprintf chan "%s\n" cmd;
|
|
|
0d20ef |
- List.iter (fun x -> fprintf chan "%s\n" x) lines
|
|
|
0d20ef |
+ (* Don't print passwords in the debug output. *)
|
|
|
0d20ef |
+ let curl_args =
|
|
|
0d20ef |
+ List.map (
|
|
|
0d20ef |
+ function
|
|
|
0d20ef |
+ | ("user", Some _) -> ("user", Some "<hidden>")
|
|
|
0d20ef |
+ | x -> x
|
|
|
0d20ef |
+ ) curl_args in
|
|
|
0d20ef |
+ (* Dump out the approximate curl command that was run. *)
|
|
|
0d20ef |
+ fprintf chan "curl -q";
|
|
|
0d20ef |
+ List.iter (
|
|
|
0d20ef |
+ function
|
|
|
0d20ef |
+ | name, None -> fprintf chan " --%s" name
|
|
|
0d20ef |
+ | name, Some value -> fprintf chan " --%s %s" name (quote value)
|
|
|
0d20ef |
+ ) curl_args;
|
|
|
0d20ef |
+ fprintf chan "\n";
|
|
|
0d20ef |
+ (* Dump out the output of the command. *)
|
|
|
0d20ef |
+ List.iter (fun x -> fprintf chan "%s\n" x) lines;
|
|
|
0d20ef |
+ flush chan
|
|
|
0d20ef |
in
|
|
|
0d20ef |
|
|
|
0d20ef |
if verbose then dump_response stdout;
|
|
|
0d20ef |
@@ -109,6 +131,39 @@ let get_session_cookie =
|
|
|
0d20ef |
Some !session_cookie
|
|
|
0d20ef |
)
|
|
|
0d20ef |
|
|
|
0d20ef |
+(* Run 'curl' and pass the arguments securely through the --config
|
|
|
0d20ef |
+ * option and an external file.
|
|
|
0d20ef |
+ *)
|
|
|
0d20ef |
+and run_curl_get_lines curl_args =
|
|
|
0d20ef |
+ let config_file, chan = Filename.open_temp_file "v2vcurl" ".conf" in
|
|
|
0d20ef |
+ List.iter (
|
|
|
0d20ef |
+ function
|
|
|
0d20ef |
+ | name, None -> fprintf chan "%s\n" name
|
|
|
0d20ef |
+ | name, Some value ->
|
|
|
0d20ef |
+ fprintf chan "%s = \"" name;
|
|
|
0d20ef |
+ (* Write the quoted value. See 'curl' man page for what is
|
|
|
0d20ef |
+ * allowed here.
|
|
|
0d20ef |
+ *)
|
|
|
0d20ef |
+ let len = String.length value in
|
|
|
0d20ef |
+ for i = 0 to len-1 do
|
|
|
0d20ef |
+ match value.[i] with
|
|
|
0d20ef |
+ | '\\' -> output_string chan "\\\\"
|
|
|
0d20ef |
+ | '"' -> output_string chan "\\\""
|
|
|
0d20ef |
+ | '\t' -> output_string chan "\\t"
|
|
|
0d20ef |
+ | '\n' -> output_string chan "\\n"
|
|
|
0d20ef |
+ | '\r' -> output_string chan "\\r"
|
|
|
0d20ef |
+ | '\x0b' -> output_string chan "\\v"
|
|
|
0d20ef |
+ | c -> output_char chan c
|
|
|
0d20ef |
+ done;
|
|
|
0d20ef |
+ fprintf chan "\"\n"
|
|
|
0d20ef |
+ ) curl_args;
|
|
|
0d20ef |
+ close_out chan;
|
|
|
0d20ef |
+
|
|
|
0d20ef |
+ let cmd = sprintf "curl -q --config %s" (quote config_file) in
|
|
|
0d20ef |
+ let lines = external_command ~prog cmd in
|
|
|
0d20ef |
+ Unix.unlink config_file;
|
|
|
0d20ef |
+ lines
|
|
|
0d20ef |
+
|
|
|
0d20ef |
(* Helper function to extract the datacenter from a URI. *)
|
|
|
0d20ef |
let get_datacenter uri scheme =
|
|
|
0d20ef |
let default_dc = "ha-datacenter" in
|
|
|
0d20ef |
--
|
|
|
0d20ef |
1.8.3.1
|
|
|
0d20ef |
|