From 289a05aa49ae751cf763b3030eda5e3e870d724e Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 21 Nov 2013 17:34:44 +0000
Subject: [PATCH] builder/sysprep: Allow 'random' as a password selector.
This chooses a random password.
(cherry picked from commit 02b5f00b2bf563d87134ad5f90ec06dbb9535bea)
---
builder/builder.ml | 34 +++++++++-------------------
builder/virt-builder.pod | 7 ++++++
mllib/password.ml | 42 +++++++++++++++++++++--------------
mllib/password.mli | 4 +++-
sysprep/sysprep_operation_password.ml | 7 ++++++
5 files changed, 53 insertions(+), 41 deletions(-)
diff --git a/builder/builder.ml b/builder/builder.ml
index e0b724b..541eb60 100644
--- a/builder/builder.ml
+++ b/builder/builder.ml
@@ -448,31 +448,19 @@ let main () =
* Note 'None' means that we randomize the root password.
*)
let () =
- let make_random_password () =
- (* Get random characters from the set [A-Za-z0-9] with some
- * homoglyphs removed.
- *)
- let chars =
- "ABCDEFGHIJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz0123456789" in
- Urandom.urandom_uniform 16 chars
- in
-
- let root_password =
- match root_password with
- | Some pw ->
- msg (f_"Setting root password");
- pw
- | None ->
- let pw = make_random_password () in
- msg (f_"Random root password: %s [did you mean to use --root-password?]")
- pw;
- Password.Set_password pw in
-
match g#inspect_get_type root with
| "linux" ->
- let h = Hashtbl.create 1 in
- Hashtbl.replace h "root" root_password;
- set_linux_passwords ~prog ?password_crypto g root h
+ let password_map = Hashtbl.create 1 in
+ let pw =
+ match root_password with
+ | Some pw ->
+ msg (f_"Setting root password");
+ pw
+ | None ->
+ msg (f_"Setting random root password [did you mean to use --root-password?]");
+ Password.Set_random_password in
+ Hashtbl.replace password_map "root" pw;
+ set_linux_passwords ~prog ?password_crypto g root password_map
| _ ->
eprintf (f_"%s: warning: root password could not be set for this type of guest\n%!") prog in
diff --git a/builder/virt-builder.pod b/builder/virt-builder.pod
index 19dc3ea..7b74bdb 100644
--- a/builder/virt-builder.pod
+++ b/builder/virt-builder.pod
@@ -705,6 +705,13 @@ Set the root password to the literal string C<PASSWORD>.
B<Note: this is not secure> since any user on the same machine can
see the cleartext password using L<ps(1)>.
+=item B<--root-password> random
+
+Choose a random password, which is printed on stdout. The password
+has approximately 120 bits of randomness.
+
+This is the default.
+
=back
=head3 Creating user accounts
diff --git a/mllib/password.ml b/mllib/password.ml
index 8cadc9d..99923d7 100644
--- a/mllib/password.ml
+++ b/mllib/password.ml
@@ -17,14 +17,24 @@
*)
open Common_gettext.Gettext
+open Common_utils
open Printf
type password_crypto = [`MD5 | `SHA256 | `SHA512 ]
-type password_selector = Set_password of string
+type password_selector =
+| Set_password of string
+| Set_random_password
type password_map = (string, password_selector) Hashtbl.t
+let make_random_password =
+ (* Get random characters from the set [A-Za-z0-9] with some
+ * homoglyphs removed.
+ *)
+ let chars = "ABCDEFGHIJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz0123456789" in
+ fun () -> Urandom.urandom_uniform 16 chars
+
let password_crypto_of_string ~prog = function
| "md5" -> `MD5
| "sha256" -> `SHA256
@@ -35,20 +45,12 @@ let password_crypto_of_string ~prog = function
exit 1
let rec parse_selector ~prog arg =
- let i =
- try String.index arg ':'
- with Not_found ->
- eprintf (f_"%s: invalid password format; see the man page.\n") prog;
- exit 1 in
- let key, value =
- let len = String.length arg in
- String.sub arg 0 i, String.sub arg (i+1) (len-(i+1)) in
-
- match key with
- | "file" -> Set_password (read_password_from_file value)
- | "password" -> Set_password value
+ match string_nsplit ":" arg with
+ | [ "file"; filename ] -> Set_password (read_password_from_file filename)
+ | "password" :: password -> Set_password (String.concat ":" password)
+ | [ "random" ] -> Set_random_password
| _ ->
- eprintf (f_"%s: password format, \"%s:...\" is not recognized; see the man page.\n") prog key;
+ eprintf (f_"%s: invalid password selector '%s'; see the man page.\n") prog arg;
exit 1
and read_password_from_file filename =
@@ -83,9 +85,15 @@ let rec set_linux_passwords ~prog ?password_crypto g root passwords =
let selector = Hashtbl.find passwords user in
let j = String.index_from line (i+1) ':' in
let rest = String.sub line j (String.length line - j) in
- match selector with
- | Set_password password ->
- user ^ ":" ^ encrypt password crypto ^ rest
+ let pwfield =
+ match selector with
+ | Set_password password -> encrypt password crypto
+ | Set_random_password ->
+ let password = make_random_password () in
+ printf (f_"Setting random password of %s to %s\n%!")
+ user password;
+ encrypt password crypto in
+ user ^ ":" ^ pwfield ^ rest
with Not_found -> line
) shadow in
diff --git a/mllib/password.mli b/mllib/password.mli
index 4c72ed7..dce9486 100644
--- a/mllib/password.mli
+++ b/mllib/password.mli
@@ -21,7 +21,9 @@ type password_crypto = [ `MD5 | `SHA256 | `SHA512 ]
val password_crypto_of_string : prog:string -> string -> password_crypto
(** Parse --password-crypto parameter on command line. *)
-type password_selector = Set_password of string
+type password_selector =
+| Set_password of string
+| Set_random_password
val parse_selector : prog:string -> string -> password_selector
(** Parse the selector field in --password/--root-password. Note this
diff --git a/sysprep/sysprep_operation_password.ml b/sysprep/sysprep_operation_password.ml
index a5c894f..0cd834a 100644
--- a/sysprep/sysprep_operation_password.ml
+++ b/sysprep/sysprep_operation_password.ml
@@ -136,6 +136,13 @@ Set the password to the literal string C<PASSWORD>.
B<Note: this is not secure> since any user on the same machine
can see the cleartext password using L<ps(1)>.
+=item B<--password USERNAME:random>
+
+=item B<--root-password random>
+
+Choose a random password, which is printed on stdout. The password
+has approximately 120 bits of randomness.
+
=back"
};
--
1.8.4.2