Commit c0f4ce7751f0b9a9a7815f931a09a6c3de127cee

Authored by aliguori
1 parent 430eb509

monitor: Rework early disk password inquiry (Jan Kiszka)

Reading the passwords for encrypted hard disks during early startup is
broken (I guess for quiet a while now):
 - No monitor terminal is ready for input at this point
 - Forcing all mux'ed terminals into monitor mode can confuse other
   users of that channels

To overcome these issues and to lay the ground for a clean decoupling of
monitor terminals, this patch changes the initial password inquiry as
follows:
 - Prevent autostart if there is some encrypted disk
 - Once the user tries to resume the VM, prompt for all missing
   passwords
 - Only resume if all passwords were accepted

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6707 c046a42c-6fe2-441c-8c8c-71466251a162
@@ -336,6 +336,7 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags, @@ -336,6 +336,7 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
336 bs->read_only = 0; 336 bs->read_only = 0;
337 bs->is_temporary = 0; 337 bs->is_temporary = 0;
338 bs->encrypted = 0; 338 bs->encrypted = 0;
  339 + bs->valid_key = 0;
339 340
340 if (flags & BDRV_O_SNAPSHOT) { 341 if (flags & BDRV_O_SNAPSHOT) {
341 BlockDriverState *bs1; 342 BlockDriverState *bs1;
@@ -966,6 +967,15 @@ int bdrv_is_encrypted(BlockDriverState *bs) @@ -966,6 +967,15 @@ int bdrv_is_encrypted(BlockDriverState *bs)
966 return bs->encrypted; 967 return bs->encrypted;
967 } 968 }
968 969
  970 +int bdrv_key_required(BlockDriverState *bs)
  971 +{
  972 + BlockDriverState *backing_hd = bs->backing_hd;
  973 +
  974 + if (backing_hd && backing_hd->encrypted && !backing_hd->valid_key)
  975 + return 1;
  976 + return (bs->encrypted && !bs->valid_key);
  977 +}
  978 +
969 int bdrv_set_key(BlockDriverState *bs, const char *key) 979 int bdrv_set_key(BlockDriverState *bs, const char *key)
970 { 980 {
971 int ret; 981 int ret;
@@ -978,7 +988,9 @@ int bdrv_set_key(BlockDriverState *bs, const char *key) @@ -978,7 +988,9 @@ int bdrv_set_key(BlockDriverState *bs, const char *key)
978 } 988 }
979 if (!bs->encrypted || !bs->drv || !bs->drv->bdrv_set_key) 989 if (!bs->encrypted || !bs->drv || !bs->drv->bdrv_set_key)
980 return -1; 990 return -1;
981 - return bs->drv->bdrv_set_key(bs, key); 991 + ret = bs->drv->bdrv_set_key(bs, key);
  992 + bs->valid_key = (ret == 0);
  993 + return ret;
982 } 994 }
983 995
984 void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size) 996 void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size)
@@ -103,8 +103,6 @@ BlockDriverAIOCB *bdrv_aio_write(BlockDriverState *bs, int64_t sector_num, @@ -103,8 +103,6 @@ BlockDriverAIOCB *bdrv_aio_write(BlockDriverState *bs, int64_t sector_num,
103 BlockDriverCompletionFunc *cb, void *opaque); 103 BlockDriverCompletionFunc *cb, void *opaque);
104 void bdrv_aio_cancel(BlockDriverAIOCB *acb); 104 void bdrv_aio_cancel(BlockDriverAIOCB *acb);
105 105
106 -int qemu_key_check(BlockDriverState *bs, const char *name);  
107 -  
108 /* Ensure contents are flushed to disk. */ 106 /* Ensure contents are flushed to disk. */
109 void bdrv_flush(BlockDriverState *bs); 107 void bdrv_flush(BlockDriverState *bs);
110 void bdrv_flush_all(void); 108 void bdrv_flush_all(void);
@@ -144,7 +142,9 @@ BlockDriverState *bdrv_find(const char *name); @@ -144,7 +142,9 @@ BlockDriverState *bdrv_find(const char *name);
144 void bdrv_iterate(void (*it)(void *opaque, BlockDriverState *bs), 142 void bdrv_iterate(void (*it)(void *opaque, BlockDriverState *bs),
145 void *opaque); 143 void *opaque);
146 int bdrv_is_encrypted(BlockDriverState *bs); 144 int bdrv_is_encrypted(BlockDriverState *bs);
  145 +int bdrv_key_required(BlockDriverState *bs);
147 int bdrv_set_key(BlockDriverState *bs, const char *key); 146 int bdrv_set_key(BlockDriverState *bs, const char *key);
  147 +int bdrv_query_missing_keys(void);
148 void bdrv_iterate_format(void (*it)(void *opaque, const char *name), 148 void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
149 void *opaque); 149 void *opaque);
150 const char *bdrv_get_device_name(BlockDriverState *bs); 150 const char *bdrv_get_device_name(BlockDriverState *bs);
block_int.h
@@ -96,6 +96,7 @@ struct BlockDriverState { @@ -96,6 +96,7 @@ struct BlockDriverState {
96 int removable; /* if true, the media can be removed */ 96 int removable; /* if true, the media can be removed */
97 int locked; /* if true, the media cannot temporarily be ejected */ 97 int locked; /* if true, the media cannot temporarily be ejected */
98 int encrypted; /* if true, the media is encrypted */ 98 int encrypted; /* if true, the media is encrypted */
  99 + int valid_key; /* if true, a valid encryption key has been set */
99 int sg; /* if true, the device is a /dev/sg* */ 100 int sg; /* if true, the device is a /dev/sg* */
100 /* event callback when inserting/removing */ 101 /* event callback when inserting/removing */
101 void (*change_cb)(void *opaque); 102 void (*change_cb)(void *opaque);
console.h
@@ -302,10 +302,9 @@ void term_printf(const char *fmt, ...) __attribute__ ((__format__ (__printf__, 1 @@ -302,10 +302,9 @@ void term_printf(const char *fmt, ...) __attribute__ ((__format__ (__printf__, 1
302 void term_print_filename(const char *filename); 302 void term_print_filename(const char *filename);
303 void term_flush(void); 303 void term_flush(void);
304 void term_print_help(void); 304 void term_print_help(void);
305 -void monitor_readline(const char *prompt, int is_password,  
306 - char *buf, int buf_size);  
307 void monitor_suspend(void); 305 void monitor_suspend(void);
308 void monitor_resume(void); 306 void monitor_resume(void);
  307 +int monitor_read_bdrv_key(BlockDriverState *bs);
309 308
310 /* readline.c */ 309 /* readline.c */
311 typedef void ReadLineFunc(void *opaque, const char *str); 310 typedef void ReadLineFunc(void *opaque, const char *str);
hw/usb-msd.c
@@ -11,6 +11,7 @@ @@ -11,6 +11,7 @@
11 #include "usb.h" 11 #include "usb.h"
12 #include "block.h" 12 #include "block.h"
13 #include "scsi-disk.h" 13 #include "scsi-disk.h"
  14 +#include "console.h"
14 15
15 //#define DEBUG_MSD 16 //#define DEBUG_MSD
16 17
@@ -513,7 +514,7 @@ static void usb_msd_handle_destroy(USBDevice *dev) @@ -513,7 +514,7 @@ static void usb_msd_handle_destroy(USBDevice *dev)
513 qemu_free(s); 514 qemu_free(s);
514 } 515 }
515 516
516 -USBDevice *usb_msd_init(const char *filename) 517 +USBDevice *usb_msd_init(const char *filename, BlockDriverState **pbs)
517 { 518 {
518 MSDState *s; 519 MSDState *s;
519 BlockDriverState *bdrv; 520 BlockDriverState *bdrv;
@@ -552,9 +553,8 @@ USBDevice *usb_msd_init(const char *filename) @@ -552,9 +553,8 @@ USBDevice *usb_msd_init(const char *filename)
552 bdrv = bdrv_new("usb"); 553 bdrv = bdrv_new("usb");
553 if (bdrv_open2(bdrv, filename, 0, drv) < 0) 554 if (bdrv_open2(bdrv, filename, 0, drv) < 0)
554 goto fail; 555 goto fail;
555 - if (qemu_key_check(bdrv, filename))  
556 - goto fail;  
557 s->bs = bdrv; 556 s->bs = bdrv;
  557 + *pbs = bdrv;
558 558
559 s->dev.speed = USB_SPEED_FULL; 559 s->dev.speed = USB_SPEED_FULL;
560 s->dev.handle_packet = usb_generic_handle_packet; 560 s->dev.handle_packet = usb_generic_handle_packet;
hw/usb.h
@@ -21,6 +21,9 @@ @@ -21,6 +21,9 @@
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE. 22 * THE SOFTWARE.
23 */ 23 */
  24 +
  25 +#include "block.h"
  26 +
24 #define USB_TOKEN_SETUP 0x2d 27 #define USB_TOKEN_SETUP 0x2d
25 #define USB_TOKEN_IN 0x69 /* device -> host */ 28 #define USB_TOKEN_IN 0x69 /* device -> host */
26 #define USB_TOKEN_OUT 0xe1 /* host -> device */ 29 #define USB_TOKEN_OUT 0xe1 /* host -> device */
@@ -250,7 +253,7 @@ USBDevice *usb_keyboard_init(void); @@ -250,7 +253,7 @@ USBDevice *usb_keyboard_init(void);
250 void usb_hid_datain_cb(USBDevice *dev, void *opaque, void (*datain)(void *)); 253 void usb_hid_datain_cb(USBDevice *dev, void *opaque, void (*datain)(void *));
251 254
252 /* usb-msd.c */ 255 /* usb-msd.c */
253 -USBDevice *usb_msd_init(const char *filename); 256 +USBDevice *usb_msd_init(const char *filename, BlockDriverState **pbs);
254 257
255 /* usb-net.c */ 258 /* usb-net.c */
256 USBDevice *usb_net_init(NICInfo *nd); 259 USBDevice *usb_net_init(NICInfo *nd);
monitor.c
@@ -76,6 +76,8 @@ static uint8_t term_outbuf[1024]; @@ -76,6 +76,8 @@ static uint8_t term_outbuf[1024];
76 static int term_outbuf_index; 76 static int term_outbuf_index;
77 77
78 static void monitor_start_input(void); 78 static void monitor_start_input(void);
  79 +static void monitor_readline(const char *prompt, int is_password,
  80 + char *buf, int buf_size);
79 81
80 static CPUState *mon_cpu = NULL; 82 static CPUState *mon_cpu = NULL;
81 83
@@ -433,7 +435,7 @@ static void do_change_block(const char *device, const char *filename, const char @@ -433,7 +435,7 @@ static void do_change_block(const char *device, const char *filename, const char
433 if (eject_device(bs, 0) < 0) 435 if (eject_device(bs, 0) < 0)
434 return; 436 return;
435 bdrv_open2(bs, filename, 0, drv); 437 bdrv_open2(bs, filename, 0, drv);
436 - qemu_key_check(bs, filename); 438 + monitor_read_bdrv_key(bs);
437 } 439 }
438 440
439 static void do_change_vnc(const char *target, const char *arg) 441 static void do_change_vnc(const char *target, const char *arg)
@@ -494,9 +496,24 @@ static void do_stop(void) @@ -494,9 +496,24 @@ static void do_stop(void)
494 vm_stop(EXCP_INTERRUPT); 496 vm_stop(EXCP_INTERRUPT);
495 } 497 }
496 498
  499 +static void encrypted_bdrv_it(void *opaque, BlockDriverState *bs)
  500 +{
  501 + int *err = opaque;
  502 +
  503 + if (bdrv_key_required(bs))
  504 + *err = monitor_read_bdrv_key(bs);
  505 + else
  506 + *err = 0;
  507 +}
  508 +
497 static void do_cont(void) 509 static void do_cont(void)
498 { 510 {
499 - vm_start(); 511 + int err = 0;
  512 +
  513 + bdrv_iterate(encrypted_bdrv_it, &err);
  514 + /* only resume the vm if all keys are set and valid */
  515 + if (!err)
  516 + vm_start();
500 } 517 }
501 518
502 #ifdef CONFIG_GDBSTUB 519 #ifdef CONFIG_GDBSTUB
@@ -2892,8 +2909,8 @@ static void monitor_readline_cb(void *opaque, const char *input) @@ -2892,8 +2909,8 @@ static void monitor_readline_cb(void *opaque, const char *input)
2892 monitor_readline_started = 0; 2909 monitor_readline_started = 0;
2893 } 2910 }
2894 2911
2895 -void monitor_readline(const char *prompt, int is_password,  
2896 - char *buf, int buf_size) 2912 +static void monitor_readline(const char *prompt, int is_password,
  2913 + char *buf, int buf_size)
2897 { 2914 {
2898 int i; 2915 int i;
2899 int old_focus[MAX_MON]; 2916 int old_focus[MAX_MON];
@@ -2923,3 +2940,22 @@ void monitor_readline(const char *prompt, int is_password, @@ -2923,3 +2940,22 @@ void monitor_readline(const char *prompt, int is_password,
2923 monitor_hd[i]->focus = old_focus[i]; 2940 monitor_hd[i]->focus = old_focus[i];
2924 } 2941 }
2925 } 2942 }
  2943 +
  2944 +int monitor_read_bdrv_key(BlockDriverState *bs)
  2945 +{
  2946 + char password[256];
  2947 + int i;
  2948 +
  2949 + if (!bdrv_is_encrypted(bs))
  2950 + return 0;
  2951 +
  2952 + term_printf("%s (%s) is encrypted.\n", bdrv_get_device_name(bs),
  2953 + bdrv_get_encrypted_filename(bs));
  2954 + for(i = 0; i < 3; i++) {
  2955 + monitor_readline("Password: ", 1, password, sizeof(password));
  2956 + if (bdrv_set_key(bs, password) == 0)
  2957 + return 0;
  2958 + term_printf("invalid password\n");
  2959 + }
  2960 + return -EPERM;
  2961 +}
@@ -201,6 +201,7 @@ ram_addr_t ram_size; @@ -201,6 +201,7 @@ ram_addr_t ram_size;
201 int nb_nics; 201 int nb_nics;
202 NICInfo nd_table[MAX_NICS]; 202 NICInfo nd_table[MAX_NICS];
203 int vm_running; 203 int vm_running;
  204 +static int autostart;
204 static int rtc_utc = 1; 205 static int rtc_utc = 1;
205 static int rtc_date_offset = -1; /* -1 means no change */ 206 static int rtc_date_offset = -1; /* -1 means no change */
206 int cirrus_vga_enabled = 1; 207 int cirrus_vga_enabled = 1;
@@ -2607,11 +2608,13 @@ int drive_init(struct drive_opt *arg, int snapshot, void *opaque) @@ -2607,11 +2608,13 @@ int drive_init(struct drive_opt *arg, int snapshot, void *opaque)
2607 bdrv_flags |= BDRV_O_CACHE_WB; 2608 bdrv_flags |= BDRV_O_CACHE_WB;
2608 else if (cache == 3) /* not specified */ 2609 else if (cache == 3) /* not specified */
2609 bdrv_flags |= BDRV_O_CACHE_DEF; 2610 bdrv_flags |= BDRV_O_CACHE_DEF;
2610 - if (bdrv_open2(bdrv, file, bdrv_flags, drv) < 0 || qemu_key_check(bdrv, file)) { 2611 + if (bdrv_open2(bdrv, file, bdrv_flags, drv) < 0) {
2611 fprintf(stderr, "qemu: could not open disk image %s\n", 2612 fprintf(stderr, "qemu: could not open disk image %s\n",
2612 file); 2613 file);
2613 return -1; 2614 return -1;
2614 } 2615 }
  2616 + if (bdrv_key_required(bdrv))
  2617 + autostart = 0;
2615 return drives_table_idx; 2618 return drives_table_idx;
2616 } 2619 }
2617 2620
@@ -2658,7 +2661,7 @@ int usb_device_add_dev(USBDevice *dev) @@ -2658,7 +2661,7 @@ int usb_device_add_dev(USBDevice *dev)
2658 return 0; 2661 return 0;
2659 } 2662 }
2660 2663
2661 -static int usb_device_add(const char *devname) 2664 +static int usb_device_add(const char *devname, int is_hotplug)
2662 { 2665 {
2663 const char *p; 2666 const char *p;
2664 USBDevice *dev; 2667 USBDevice *dev;
@@ -2675,7 +2678,18 @@ static int usb_device_add(const char *devname) @@ -2675,7 +2678,18 @@ static int usb_device_add(const char *devname)
2675 } else if (!strcmp(devname, "keyboard")) { 2678 } else if (!strcmp(devname, "keyboard")) {
2676 dev = usb_keyboard_init(); 2679 dev = usb_keyboard_init();
2677 } else if (strstart(devname, "disk:", &p)) { 2680 } else if (strstart(devname, "disk:", &p)) {
2678 - dev = usb_msd_init(p); 2681 + BlockDriverState *bs;
  2682 +
  2683 + dev = usb_msd_init(p, &bs);
  2684 + if (!dev)
  2685 + return -1;
  2686 + if (bdrv_key_required(bs)) {
  2687 + autostart = 0;
  2688 + if (is_hotplug && monitor_read_bdrv_key(bs) < 0) {
  2689 + dev->handle_destroy(dev);
  2690 + return -1;
  2691 + }
  2692 + }
2679 } else if (!strcmp(devname, "wacom-tablet")) { 2693 } else if (!strcmp(devname, "wacom-tablet")) {
2680 dev = usb_wacom_init(); 2694 dev = usb_wacom_init();
2681 } else if (strstart(devname, "serial:", &p)) { 2695 } else if (strstart(devname, "serial:", &p)) {
@@ -2756,7 +2770,7 @@ static int usb_device_del(const char *devname) @@ -2756,7 +2770,7 @@ static int usb_device_del(const char *devname)
2756 2770
2757 void do_usb_add(const char *devname) 2771 void do_usb_add(const char *devname)
2758 { 2772 {
2759 - usb_device_add(devname); 2773 + usb_device_add(devname, 1);
2760 } 2774 }
2761 2775
2762 void do_usb_del(const char *devname) 2776 void do_usb_del(const char *devname)
@@ -4334,45 +4348,6 @@ static const QEMUOption qemu_options[] = { @@ -4334,45 +4348,6 @@ static const QEMUOption qemu_options[] = {
4334 { NULL }, 4348 { NULL },
4335 }; 4349 };
4336 4350
4337 -/* password input */  
4338 -  
4339 -int qemu_key_check(BlockDriverState *bs, const char *name)  
4340 -{  
4341 - char password[256];  
4342 - int i;  
4343 -  
4344 - if (!bdrv_is_encrypted(bs))  
4345 - return 0;  
4346 -  
4347 - term_printf("%s is encrypted.\n", name);  
4348 - for(i = 0; i < 3; i++) {  
4349 - monitor_readline("Password: ", 1, password, sizeof(password));  
4350 - if (bdrv_set_key(bs, password) == 0)  
4351 - return 0;  
4352 - term_printf("invalid password\n");  
4353 - }  
4354 - return -EPERM;  
4355 -}  
4356 -  
4357 -static BlockDriverState *get_bdrv(int index)  
4358 -{  
4359 - if (index > nb_drives)  
4360 - return NULL;  
4361 - return drives_table[index].bdrv;  
4362 -}  
4363 -  
4364 -static void read_passwords(void)  
4365 -{  
4366 - BlockDriverState *bs;  
4367 - int i;  
4368 -  
4369 - for(i = 0; i < 6; i++) {  
4370 - bs = get_bdrv(i);  
4371 - if (bs)  
4372 - qemu_key_check(bs, bdrv_get_device_name(bs));  
4373 - }  
4374 -}  
4375 -  
4376 #ifdef HAS_AUDIO 4351 #ifdef HAS_AUDIO
4377 struct soundhw soundhw[] = { 4352 struct soundhw soundhw[] = {
4378 #ifdef HAS_AUDIO_CHOICE 4353 #ifdef HAS_AUDIO_CHOICE
@@ -4639,7 +4614,6 @@ int main(int argc, char **argv, char **envp) @@ -4639,7 +4614,6 @@ int main(int argc, char **argv, char **envp)
4639 int fds[2]; 4614 int fds[2];
4640 int tb_size; 4615 int tb_size;
4641 const char *pid_file = NULL; 4616 const char *pid_file = NULL;
4642 - int autostart;  
4643 const char *incoming = NULL; 4617 const char *incoming = NULL;
4644 int fd = 0; 4618 int fd = 0;
4645 struct passwd *pwd = NULL; 4619 struct passwd *pwd = NULL;
@@ -5637,7 +5611,7 @@ int main(int argc, char **argv, char **envp) @@ -5637,7 +5611,7 @@ int main(int argc, char **argv, char **envp)
5637 /* init USB devices */ 5611 /* init USB devices */
5638 if (usb_enabled) { 5612 if (usb_enabled) {
5639 for(i = 0; i < usb_devices_index; i++) { 5613 for(i = 0; i < usb_devices_index; i++) {
5640 - if (usb_device_add(usb_devices[i]) < 0) { 5614 + if (usb_device_add(usb_devices[i], 0) < 0) {
5641 fprintf(stderr, "Warning: could not add USB device %s\n", 5615 fprintf(stderr, "Warning: could not add USB device %s\n",
5642 usb_devices[i]); 5616 usb_devices[i]);
5643 } 5617 }
@@ -5748,13 +5722,8 @@ int main(int argc, char **argv, char **envp) @@ -5748,13 +5722,8 @@ int main(int argc, char **argv, char **envp)
5748 qemu_start_incoming_migration(incoming); 5722 qemu_start_incoming_migration(incoming);
5749 } 5723 }
5750 5724
5751 - {  
5752 - /* XXX: simplify init */  
5753 - read_passwords();  
5754 - if (autostart) {  
5755 - vm_start();  
5756 - }  
5757 - } 5725 + if (autostart)
  5726 + vm_start();
5758 5727
5759 if (daemonize) { 5728 if (daemonize) {
5760 uint8_t status = 0; 5729 uint8_t status = 0;