int main(int argc, char **argv) { g_test_init(&argc, &argv, NULL); module_call_init(MODULE_INIT_QOM); type_register_static(&static_prop_type); type_register_static(&dynamic_prop_type); type_register_static(&hotplug_type); type_register_static(&nohotplug_type); type_register_static(&nondevice_type); g_test_add_func("/qdev/properties/static/default/subprocess", test_static_prop_subprocess); g_test_add_func("/qdev/properties/static/default", test_static_prop); g_test_add_func("/qdev/properties/static/global/subprocess", test_static_globalprop_subprocess); g_test_add_func("/qdev/properties/static/global", test_static_globalprop); g_test_add_func("/qdev/properties/dynamic/global/subprocess", test_dynamic_globalprop_subprocess); g_test_add_func("/qdev/properties/dynamic/global", test_dynamic_globalprop); g_test_add_func("/qdev/properties/dynamic/global/nouser/subprocess", test_dynamic_globalprop_nouser_subprocess); g_test_add_func("/qdev/properties/dynamic/global/nouser", test_dynamic_globalprop_nouser); g_test_run(); return 0; }
int main(int argc, char **argv) { int ret; TestState ts = { 0 }; ts.src_tpm_path = g_dir_make_tmp("qemu-tpm-tis-swtpm-test.XXXXXX", NULL); ts.dst_tpm_path = g_dir_make_tmp("qemu-tpm-tis-swtpm-test.XXXXXX", NULL); ts.uri = g_strdup_printf("unix:%s/migsocket", ts.src_tpm_path); module_call_init(MODULE_INIT_QOM); g_test_init(&argc, &argv, NULL); qtest_add_data_func("/tpm/tis-swtpm/test", &ts, tpm_tis_swtpm_test); qtest_add_data_func("/tpm/tis-swtpm-migration/test", &ts, tpm_tis_swtpm_migration_test); ret = g_test_run(); g_rmdir(ts.dst_tpm_path); g_free(ts.dst_tpm_path); g_rmdir(ts.src_tpm_path); g_free(ts.src_tpm_path); g_free(ts.uri); return ret; }
int main(int argc, char **argv) { QTestState *s = NULL; CharDriverState *chr = NULL; const char *hugefs = 0; char *socket_path = 0; char *qemu_cmd = 0; char *chr_path = 0; int ret; g_test_init(&argc, &argv, NULL); module_call_init(MODULE_INIT_QOM); hugefs = init_hugepagefs(); if (!hugefs) { return 0; } socket_path = g_strdup_printf("/tmp/vhost-%d.sock", getpid()); /* create char dev and add read handlers */ qemu_add_opts(&qemu_chardev_opts); chr_path = g_strdup_printf("unix:%s,server,nowait", socket_path); chr = qemu_chr_new("chr0", chr_path, NULL); g_free(chr_path); qemu_chr_add_handlers(chr, chr_can_read, chr_read, NULL, chr); /* run the main loop thread so the chardev may operate */ data_mutex = _mutex_new(); data_cond = _cond_new(); _thread_new(NULL, thread_function, NULL); qemu_cmd = g_strdup_printf(QEMU_CMD, hugefs, socket_path); s = qtest_start(qemu_cmd); g_free(qemu_cmd); qtest_add_func("/vhost-user/read-guest-mem", read_guest_mem); ret = g_test_run(); if (s) { qtest_quit(s); } /* cleanup */ unlink(socket_path); g_free(socket_path); _cond_free(data_cond); _mutex_free(data_mutex); return ret; }
int machine_initialize(struct uc_struct *uc) { MachineClass *machine_class; MachineState *current_machine; module_call_init(uc, MODULE_INIT_QOM); register_types_object(uc); machine_register_types(uc); container_register_types(uc); cpu_register_types(uc); qdev_register_types(uc); // Initialize arch specific. uc->init_arch(uc); module_call_init(uc, MODULE_INIT_MACHINE); // this will auto initialize all register objects above. machine_class = find_default_machine(uc, uc->arch); if (machine_class == NULL) { //fprintf(stderr, "No machine specified, and there is no default.\n" // "Use -machine help to list supported machines!\n"); return -2; } current_machine = MACHINE(uc, object_new(uc, object_class_get_name( OBJECT_CLASS(machine_class)))); current_machine->uc = uc; uc->cpu_exec_init_all(uc); machine_class->max_cpus = 1; configure_accelerator(current_machine); qemu_init_cpu_loop(uc); qemu_mutex_lock_iothread(uc); current_machine->cpu_model = NULL; return machine_class->init(uc, current_machine); }
int main(int argc, char **argv) { g_test_init(&argc, &argv, NULL); g_test_add_func("/0.15/dispatch_cmd", test_dispatch_cmd); g_test_add_func("/0.15/dispatch_cmd_error", test_dispatch_cmd_error); g_test_add_func("/0.15/dispatch_cmd_io", test_dispatch_cmd_io); module_call_init(MODULE_INIT_QAPI); g_test_run(); return 0; }
int main(int argc, char **argv) { module_call_init(MODULE_INIT_QOM); g_test_init(&argc, &argv, NULL); g_test_add_func("/io/channel/file", test_io_channel_file); #ifndef _WIN32 g_test_add_func("/io/channel/pipe/sync", test_io_channel_pipe_sync); g_test_add_func("/io/channel/pipe/async", test_io_channel_pipe_async); #endif return g_test_run(); }
int main(int argc, char **argv) { g_test_init(&argc, &argv, NULL); module_call_init(MODULE_INIT_QOM); type_register_static(&dummy_info); g_test_add_func("/qom/proplist/createlist", test_dummy_createlist); g_test_add_func("/qom/proplist/createv", test_dummy_createv); g_test_add_func("/qom/proplist/badenum", test_dummy_badenum); g_test_add_func("/qom/proplist/getenum", test_dummy_getenum); return g_test_run(); }
int main(int argc, char **argv) { bool has_ipv4, has_ipv6; module_call_init(MODULE_INIT_QOM); socket_init(); g_test_init(&argc, &argv, NULL); /* We're creating actual IPv4/6 sockets, so we should * check if the host running tests actually supports * each protocol to avoid breaking tests on machines * with either IPv4 or IPv6 disabled. */ if (socket_check_protocol_support(&has_ipv4, &has_ipv6) < 0) { return 1; } if (has_ipv4) { g_test_add_func("/io/channel/socket/ipv4-sync", test_io_channel_ipv4_sync); g_test_add_func("/io/channel/socket/ipv4-async", test_io_channel_ipv4_async); g_test_add_func("/io/channel/socket/ipv4-fd", test_io_channel_ipv4_fd); } if (has_ipv6) { g_test_add_func("/io/channel/socket/ipv6-sync", test_io_channel_ipv6_sync); g_test_add_func("/io/channel/socket/ipv6-async", test_io_channel_ipv6_async); } #ifndef _WIN32 g_test_add_func("/io/channel/socket/unix-sync", test_io_channel_unix_sync); g_test_add_func("/io/channel/socket/unix-async", test_io_channel_unix_async); g_test_add_func("/io/channel/socket/unix-fd-pass", test_io_channel_unix_fd_pass); g_test_add_func("/io/channel/socket/unix-listen-cleanup", test_io_channel_unix_listen_cleanup); #endif /* _WIN32 */ return g_test_run(); }
int main(int argc, char **argv) { module_call_init(MODULE_INIT_QOM); g_test_init(&argc, &argv, NULL); g_assert(qcrypto_init(NULL) == 0); g_test_add_func("/crypto/secret/direct", test_secret_direct); g_test_add_func("/crypto/secret/indirect/good", test_secret_indirect_good); g_test_add_func("/crypto/secret/indirect/badfile", test_secret_indirect_badfile); g_test_add_func("/crypto/secret/indirect/emptyfile", test_secret_indirect_emptyfile); g_test_add_func("/crypto/secret/noconv/base64/good", test_secret_noconv_base64_good); g_test_add_func("/crypto/secret/noconv/base64/bad", test_secret_noconv_base64_bad); g_test_add_func("/crypto/secret/noconv/utf8", test_secret_noconv_utf8); g_test_add_func("/crypto/secret/conv/base64/utf8valid", test_secret_conv_base64_utf8valid); g_test_add_func("/crypto/secret/conv/base64/utf8invalid", test_secret_conv_base64_utf8invalid); g_test_add_func("/crypto/secret/conv/utf8/base64", test_secret_conv_utf8_base64); g_test_add_func("/crypto/secret/crypt/raw", test_secret_crypt_raw); g_test_add_func("/crypto/secret/crypt/base64", test_secret_crypt_base64); g_test_add_func("/crypto/secret/crypt/shortkey", test_secret_crypt_short_key); g_test_add_func("/crypto/secret/crypt/shortiv", test_secret_crypt_short_iv); g_test_add_func("/crypto/secret/crypt/missingiv", test_secret_crypt_missing_iv); g_test_add_func("/crypto/secret/crypt/badiv", test_secret_crypt_bad_iv); return g_test_run(); }
int main(int argc, char **argv) { g_test_init(&argc, &argv, NULL); module_call_init(MODULE_INIT_QOM); type_register_static(&dummy_info); type_register_static(&dummy_dev_info); type_register_static(&dummy_bus_info); type_register_static(&dummy_backend_info); g_test_add_func("/qom/proplist/createlist", test_dummy_createlist); g_test_add_func("/qom/proplist/createv", test_dummy_createv); g_test_add_func("/qom/proplist/createcmdline", test_dummy_createcmdl); g_test_add_func("/qom/proplist/badenum", test_dummy_badenum); g_test_add_func("/qom/proplist/getenum", test_dummy_getenum); g_test_add_func("/qom/proplist/iterator", test_dummy_iterator); g_test_add_func("/qom/proplist/class_iterator", test_dummy_class_iterator); g_test_add_func("/qom/proplist/delchild", test_dummy_delchild); g_test_add_func("/qom/resolve/partial", test_qom_partial_path); return g_test_run(); }
int main(int argc, char **argv) { const char *sopt = "hVvdm:p:l:f:F::b:s:t:"; const char *method = NULL, *path = NULL; const char *log_filepath = NULL; const char *pid_filepath; #ifdef CONFIG_FSFREEZE const char *fsfreeze_hook = NULL; #endif const char *state_dir; #ifdef _WIN32 const char *service = NULL; #endif const struct option lopt[] = { { "help", 0, NULL, 'h' }, { "version", 0, NULL, 'V' }, { "logfile", 1, NULL, 'l' }, { "pidfile", 1, NULL, 'f' }, #ifdef CONFIG_FSFREEZE { "fsfreeze-hook", 2, NULL, 'F' }, #endif { "verbose", 0, NULL, 'v' }, { "method", 1, NULL, 'm' }, { "path", 1, NULL, 'p' }, { "daemonize", 0, NULL, 'd' }, { "blacklist", 1, NULL, 'b' }, #ifdef _WIN32 { "service", 1, NULL, 's' }, #endif { "statedir", 1, NULL, 't' }, { NULL, 0, NULL, 0 } }; int opt_ind = 0, ch, daemonize = 0, i, j, len; GLogLevelFlags log_level = G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL; GList *blacklist = NULL; GAState *s; module_call_init(MODULE_INIT_QAPI); init_dfl_pathnames(); pid_filepath = dfl_pathnames.pidfile; state_dir = dfl_pathnames.state_dir; while ((ch = getopt_long(argc, argv, sopt, lopt, &opt_ind)) != -1) { switch (ch) { case 'm': method = optarg; break; case 'p': path = optarg; break; case 'l': log_filepath = optarg; break; case 'f': pid_filepath = optarg; break; #ifdef CONFIG_FSFREEZE case 'F': fsfreeze_hook = optarg ? optarg : QGA_FSFREEZE_HOOK_DEFAULT; break; #endif case 't': state_dir = optarg; break; case 'v': /* enable all log levels */ log_level = G_LOG_LEVEL_MASK; break; case 'V': printf("QEMU Guest Agent %s\n", QEMU_VERSION); return 0; case 'd': daemonize = 1; break; case 'b': { if (is_help_option(optarg)) { qmp_for_each_command(ga_print_cmd, NULL); return 0; } for (j = 0, i = 0, len = strlen(optarg); i < len; i++) { if (optarg[i] == ',') { optarg[i] = 0; blacklist = g_list_append(blacklist, &optarg[j]); j = i + 1; } } if (j < i) { blacklist = g_list_append(blacklist, &optarg[j]); } break; } #ifdef _WIN32 case 's': service = optarg; if (strcmp(service, "install") == 0) { const char *fixed_state_dir; /* If the user passed the "-t" option, we save that state dir * in the service. Otherwise we let the service fetch the state * dir from the environment when it starts. */ fixed_state_dir = (state_dir == dfl_pathnames.state_dir) ? NULL : state_dir; if (ga_install_vss_provider()) { return EXIT_FAILURE; } if (ga_install_service(path, log_filepath, fixed_state_dir)) { return EXIT_FAILURE; } return 0; } else if (strcmp(service, "uninstall") == 0) { ga_uninstall_vss_provider(); return ga_uninstall_service(); } else { printf("Unknown service command.\n"); return EXIT_FAILURE; } break; #endif case 'h': usage(argv[0]); return 0; case '?': g_print("Unknown option, try '%s --help' for more information.\n", argv[0]); return EXIT_FAILURE; } } #ifdef _WIN32 /* On win32 the state directory is application specific (be it the default * or a user override). We got past the command line parsing; let's create * the directory (with any intermediate directories). If we run into an * error later on, we won't try to clean up the directory, it is considered * persistent. */ if (g_mkdir_with_parents(state_dir, S_IRWXU) == -1) { g_critical("unable to create (an ancestor of) the state directory" " '%s': %s", state_dir, strerror(errno)); return EXIT_FAILURE; } #endif s = g_malloc0(sizeof(GAState)); s->log_level = log_level; s->log_file = stderr; #ifdef CONFIG_FSFREEZE s->fsfreeze_hook = fsfreeze_hook; #endif g_log_set_default_handler(ga_log, s); g_log_set_fatal_mask(NULL, G_LOG_LEVEL_ERROR); ga_enable_logging(s); s->state_filepath_isfrozen = g_strdup_printf("%s/qga.state.isfrozen", state_dir); s->pstate_filepath = g_strdup_printf("%s/qga.state", state_dir); s->frozen = false; #ifndef _WIN32 /* check if a previous instance of qemu-ga exited with filesystems' state * marked as frozen. this could be a stale value (a non-qemu-ga process * or reboot may have since unfrozen them), but better to require an * uneeded unfreeze than to risk hanging on start-up */ struct stat st; if (stat(s->state_filepath_isfrozen, &st) == -1) { /* it's okay if the file doesn't exist, but if we can't access for * some other reason, such as permissions, there's a configuration * that needs to be addressed. so just bail now before we get into * more trouble later */ if (errno != ENOENT) { g_critical("unable to access state file at path %s: %s", s->state_filepath_isfrozen, strerror(errno)); return EXIT_FAILURE; } } else { g_warning("previous instance appears to have exited with frozen" " filesystems. deferring logging/pidfile creation and" " disabling non-fsfreeze-safe commands until" " guest-fsfreeze-thaw is issued, or filesystems are" " manually unfrozen and the file %s is removed", s->state_filepath_isfrozen); s->frozen = true; } #endif if (ga_is_frozen(s)) { if (daemonize) { /* delay opening/locking of pidfile till filesystems are unfrozen */ s->deferred_options.pid_filepath = pid_filepath; become_daemon(NULL); } if (log_filepath) { /* delay opening the log file till filesystems are unfrozen */ s->deferred_options.log_filepath = log_filepath; } ga_disable_logging(s); qmp_for_each_command(ga_disable_non_whitelisted, NULL); } else { if (daemonize) { become_daemon(pid_filepath); } if (log_filepath) { FILE *log_file = ga_open_logfile(log_filepath); if (!log_file) { g_critical("unable to open specified log file: %s", strerror(errno)); goto out_bad; } s->log_file = log_file; } } /* load persistent state from disk */ if (!read_persistent_state(&s->pstate, s->pstate_filepath, ga_is_frozen(s))) { g_critical("failed to load persistent state"); goto out_bad; } blacklist = ga_command_blacklist_init(blacklist); if (blacklist) { s->blacklist = blacklist; do { g_debug("disabling command: %s", (char *)blacklist->data); qmp_disable_command(blacklist->data); blacklist = g_list_next(blacklist); } while (blacklist); } s->command_state = ga_command_state_new(); ga_command_state_init(s, s->command_state); ga_command_state_init_all(s->command_state); json_message_parser_init(&s->parser, process_event); ga_state = s; #ifndef _WIN32 if (!register_signal_handlers()) { g_critical("failed to register signal handlers"); goto out_bad; } #endif s->main_loop = g_main_loop_new(NULL, false); if (!channel_init(ga_state, method, path)) { g_critical("failed to initialize guest agent channel"); goto out_bad; } #ifndef _WIN32 g_main_loop_run(ga_state->main_loop); #else if (daemonize) { SERVICE_TABLE_ENTRY service_table[] = { { (char *)QGA_SERVICE_NAME, service_main }, { NULL, NULL } }; StartServiceCtrlDispatcher(service_table); } else { g_main_loop_run(ga_state->main_loop); } #endif ga_command_state_cleanup_all(ga_state->command_state); ga_channel_free(ga_state->channel); if (daemonize) { unlink(pid_filepath); } return 0; out_bad: if (daemonize) { unlink(pid_filepath); } return EXIT_FAILURE; }
int main(int argc, char **argv) { BlockBackend *blk; BlockDriverState *bs; off_t dev_offset = 0; uint16_t nbdflags = 0; bool disconnect = false; const char *bindto = NULL; const char *port = NULL; char *sockpath = NULL; char *device = NULL; off_t fd_size; QemuOpts *sn_opts = NULL; const char *sn_id_or_name = NULL; const char *sopt = "hVb:o:p:rsnP:c:dvk:e:f:tl:x:T:D:"; struct option lopt[] = { { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, 'V' }, { "bind", required_argument, NULL, 'b' }, { "port", required_argument, NULL, 'p' }, { "socket", required_argument, NULL, 'k' }, { "offset", required_argument, NULL, 'o' }, { "read-only", no_argument, NULL, 'r' }, { "partition", required_argument, NULL, 'P' }, { "connect", required_argument, NULL, 'c' }, { "disconnect", no_argument, NULL, 'd' }, { "snapshot", no_argument, NULL, 's' }, { "load-snapshot", required_argument, NULL, 'l' }, { "nocache", no_argument, NULL, 'n' }, { "cache", required_argument, NULL, QEMU_NBD_OPT_CACHE }, { "aio", required_argument, NULL, QEMU_NBD_OPT_AIO }, { "discard", required_argument, NULL, QEMU_NBD_OPT_DISCARD }, { "detect-zeroes", required_argument, NULL, QEMU_NBD_OPT_DETECT_ZEROES }, { "shared", required_argument, NULL, 'e' }, { "format", required_argument, NULL, 'f' }, { "persistent", no_argument, NULL, 't' }, { "verbose", no_argument, NULL, 'v' }, { "object", required_argument, NULL, QEMU_NBD_OPT_OBJECT }, { "export-name", required_argument, NULL, 'x' }, { "description", required_argument, NULL, 'D' }, { "tls-creds", required_argument, NULL, QEMU_NBD_OPT_TLSCREDS }, { "image-opts", no_argument, NULL, QEMU_NBD_OPT_IMAGE_OPTS }, { "trace", required_argument, NULL, 'T' }, { "fork", no_argument, NULL, QEMU_NBD_OPT_FORK }, { NULL, 0, NULL, 0 } }; int ch; int opt_ind = 0; char *end; int flags = BDRV_O_RDWR; int partition = -1; int ret = 0; bool seen_cache = false; bool seen_discard = false; bool seen_aio = false; pthread_t client_thread; const char *fmt = NULL; Error *local_err = NULL; BlockdevDetectZeroesOptions detect_zeroes = BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF; QDict *options = NULL; const char *export_name = NULL; const char *export_description = NULL; const char *tlscredsid = NULL; bool imageOpts = false; bool writethrough = true; char *trace_file = NULL; bool fork_process = false; int old_stderr = -1; unsigned socket_activation; /* The client thread uses SIGTERM to interrupt the server. A signal * handler ensures that "qemu-nbd -v -c" exits with a nice status code. */ struct sigaction sa_sigterm; memset(&sa_sigterm, 0, sizeof(sa_sigterm)); sa_sigterm.sa_handler = termsig_handler; sigaction(SIGTERM, &sa_sigterm, NULL); #ifdef CONFIG_POSIX signal(SIGPIPE, SIG_IGN); #endif module_call_init(MODULE_INIT_TRACE); qcrypto_init(&error_fatal); module_call_init(MODULE_INIT_QOM); qemu_add_opts(&qemu_object_opts); qemu_add_opts(&qemu_trace_opts); qemu_init_exec_dir(argv[0]); while ((ch = getopt_long(argc, argv, sopt, lopt, &opt_ind)) != -1) { switch (ch) { case 's': flags |= BDRV_O_SNAPSHOT; break; case 'n': optarg = (char *) "none"; /* fallthrough */ case QEMU_NBD_OPT_CACHE: if (seen_cache) { error_report("-n and --cache can only be specified once"); exit(EXIT_FAILURE); } seen_cache = true; if (bdrv_parse_cache_mode(optarg, &flags, &writethrough) == -1) { error_report("Invalid cache mode `%s'", optarg); exit(EXIT_FAILURE); } break; case QEMU_NBD_OPT_AIO: if (seen_aio) { error_report("--aio can only be specified once"); exit(EXIT_FAILURE); } seen_aio = true; if (!strcmp(optarg, "native")) { flags |= BDRV_O_NATIVE_AIO; } else if (!strcmp(optarg, "threads")) { /* this is the default */ } else { error_report("invalid aio mode `%s'", optarg); exit(EXIT_FAILURE); } break; case QEMU_NBD_OPT_DISCARD: if (seen_discard) { error_report("--discard can only be specified once"); exit(EXIT_FAILURE); } seen_discard = true; if (bdrv_parse_discard_flags(optarg, &flags) == -1) { error_report("Invalid discard mode `%s'", optarg); exit(EXIT_FAILURE); } break; case QEMU_NBD_OPT_DETECT_ZEROES: detect_zeroes = qapi_enum_parse(BlockdevDetectZeroesOptions_lookup, optarg, BLOCKDEV_DETECT_ZEROES_OPTIONS__MAX, BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF, &local_err); if (local_err) { error_reportf_err(local_err, "Failed to parse detect_zeroes mode: "); exit(EXIT_FAILURE); } if (detect_zeroes == BLOCKDEV_DETECT_ZEROES_OPTIONS_UNMAP && !(flags & BDRV_O_UNMAP)) { error_report("setting detect-zeroes to unmap is not allowed " "without setting discard operation to unmap"); exit(EXIT_FAILURE); } break; case 'b': bindto = optarg; break; case 'p': port = optarg; break; case 'o': dev_offset = strtoll (optarg, &end, 0); if (*end) { error_report("Invalid offset `%s'", optarg); exit(EXIT_FAILURE); } if (dev_offset < 0) { error_report("Offset must be positive `%s'", optarg); exit(EXIT_FAILURE); } break; case 'l': if (strstart(optarg, SNAPSHOT_OPT_BASE, NULL)) { sn_opts = qemu_opts_parse_noisily(&internal_snapshot_opts, optarg, false); if (!sn_opts) { error_report("Failed in parsing snapshot param `%s'", optarg); exit(EXIT_FAILURE); } } else { sn_id_or_name = optarg; } /* fall through */ case 'r': nbdflags |= NBD_FLAG_READ_ONLY; flags &= ~BDRV_O_RDWR; break; case 'P': partition = strtol(optarg, &end, 0); if (*end) { error_report("Invalid partition `%s'", optarg); exit(EXIT_FAILURE); } if (partition < 1 || partition > 8) { error_report("Invalid partition %d", partition); exit(EXIT_FAILURE); } break; case 'k': sockpath = optarg; if (sockpath[0] != '/') { error_report("socket path must be absolute"); exit(EXIT_FAILURE); } break; case 'd': disconnect = true; break; case 'c': device = optarg; break; case 'e': shared = strtol(optarg, &end, 0); if (*end) { error_report("Invalid shared device number '%s'", optarg); exit(EXIT_FAILURE); } if (shared < 1) { error_report("Shared device number must be greater than 0"); exit(EXIT_FAILURE); } break; case 'f': fmt = optarg; break; case 't': persistent = 1; break; case 'x': export_name = optarg; break; case 'D': export_description = optarg; break; case 'v': verbose = 1; break; case 'V': version(argv[0]); exit(0); break; case 'h': usage(argv[0]); exit(0); break; case '?': error_report("Try `%s --help' for more information.", argv[0]); exit(EXIT_FAILURE); case QEMU_NBD_OPT_OBJECT: { QemuOpts *opts; opts = qemu_opts_parse_noisily(&qemu_object_opts, optarg, true); if (!opts) { exit(EXIT_FAILURE); } } break; case QEMU_NBD_OPT_TLSCREDS: tlscredsid = optarg; break; case QEMU_NBD_OPT_IMAGE_OPTS: imageOpts = true; break; case 'T': g_free(trace_file); trace_file = trace_opt_parse(optarg); break; case QEMU_NBD_OPT_FORK: fork_process = true; break; } } if ((argc - optind) != 1) { error_report("Invalid number of arguments"); error_printf("Try `%s --help' for more information.\n", argv[0]); exit(EXIT_FAILURE); } if (qemu_opts_foreach(&qemu_object_opts, user_creatable_add_opts_foreach, NULL, NULL)) { exit(EXIT_FAILURE); } if (!trace_init_backends()) { exit(1); } trace_init_file(trace_file); qemu_set_log(LOG_TRACE); socket_activation = check_socket_activation(); if (socket_activation == 0) { setup_address_and_port(&bindto, &port); } else { /* Using socket activation - check user didn't use -p etc. */ const char *err_msg = socket_activation_validate_opts(device, sockpath, bindto, port); if (err_msg != NULL) { error_report("%s", err_msg); exit(EXIT_FAILURE); } /* qemu-nbd can only listen on a single socket. */ if (socket_activation > 1) { error_report("qemu-nbd does not support socket activation with %s > 1", "LISTEN_FDS"); exit(EXIT_FAILURE); } } if (tlscredsid) { if (sockpath) { error_report("TLS is only supported with IPv4/IPv6"); exit(EXIT_FAILURE); } if (device) { error_report("TLS is not supported with a host device"); exit(EXIT_FAILURE); } if (!export_name) { /* Set the default NBD protocol export name, since * we *must* use new style protocol for TLS */ export_name = ""; } tlscreds = nbd_get_tls_creds(tlscredsid, &local_err); if (local_err) { error_report("Failed to get TLS creds %s", error_get_pretty(local_err)); exit(EXIT_FAILURE); } } if (disconnect) { int nbdfd = open(argv[optind], O_RDWR); if (nbdfd < 0) { error_report("Cannot open %s: %s", argv[optind], strerror(errno)); exit(EXIT_FAILURE); } nbd_disconnect(nbdfd); close(nbdfd); printf("%s disconnected\n", argv[optind]); return 0; } if ((device && !verbose) || fork_process) { int stderr_fd[2]; pid_t pid; int ret; if (qemu_pipe(stderr_fd) < 0) { error_report("Error setting up communication pipe: %s", strerror(errno)); exit(EXIT_FAILURE); } /* Now daemonize, but keep a communication channel open to * print errors and exit with the proper status code. */ pid = fork(); if (pid < 0) { error_report("Failed to fork: %s", strerror(errno)); exit(EXIT_FAILURE); } else if (pid == 0) { close(stderr_fd[0]); ret = qemu_daemon(1, 0); /* Temporarily redirect stderr to the parent's pipe... */ old_stderr = dup(STDERR_FILENO); dup2(stderr_fd[1], STDERR_FILENO); if (ret < 0) { error_report("Failed to daemonize: %s", strerror(errno)); exit(EXIT_FAILURE); } /* ... close the descriptor we inherited and go on. */ close(stderr_fd[1]); } else { bool errors = false; char *buf; /* In the parent. Print error messages from the child until * it closes the pipe. */ close(stderr_fd[1]); buf = g_malloc(1024); while ((ret = read(stderr_fd[0], buf, 1024)) > 0) { errors = true; ret = qemu_write_full(STDERR_FILENO, buf, ret); if (ret < 0) { exit(EXIT_FAILURE); } } if (ret < 0) { error_report("Cannot read from daemon: %s", strerror(errno)); exit(EXIT_FAILURE); } /* Usually the daemon should not print any message. * Exit with zero status in that case. */ exit(errors); } } if (device != NULL && sockpath == NULL) { sockpath = g_malloc(128); snprintf(sockpath, 128, SOCKET_PATH, basename(device)); } if (socket_activation == 0) { server_ioc = qio_channel_socket_new(); saddr = nbd_build_socket_address(sockpath, bindto, port); if (qio_channel_socket_listen_sync(server_ioc, saddr, &local_err) < 0) { object_unref(OBJECT(server_ioc)); error_report_err(local_err); return 1; } } else { /* See comment in check_socket_activation above. */ assert(socket_activation == 1); server_ioc = qio_channel_socket_new_fd(FIRST_SOCKET_ACTIVATION_FD, &local_err); if (server_ioc == NULL) { error_report("Failed to use socket activation: %s", error_get_pretty(local_err)); exit(EXIT_FAILURE); } } if (qemu_init_main_loop(&local_err)) { error_report_err(local_err); exit(EXIT_FAILURE); } bdrv_init(); atexit(bdrv_close_all); srcpath = argv[optind]; if (imageOpts) { QemuOpts *opts; if (fmt) { error_report("--image-opts and -f are mutually exclusive"); exit(EXIT_FAILURE); } opts = qemu_opts_parse_noisily(&file_opts, srcpath, true); if (!opts) { qemu_opts_reset(&file_opts); exit(EXIT_FAILURE); } options = qemu_opts_to_qdict(opts, NULL); qemu_opts_reset(&file_opts); blk = blk_new_open(NULL, NULL, options, flags, &local_err); } else { if (fmt) { options = qdict_new(); qdict_put_str(options, "driver", fmt); } blk = blk_new_open(srcpath, NULL, options, flags, &local_err); } if (!blk) { error_reportf_err(local_err, "Failed to blk_new_open '%s': ", argv[optind]); exit(EXIT_FAILURE); } bs = blk_bs(blk); blk_set_enable_write_cache(blk, !writethrough); if (sn_opts) { ret = bdrv_snapshot_load_tmp(bs, qemu_opt_get(sn_opts, SNAPSHOT_OPT_ID), qemu_opt_get(sn_opts, SNAPSHOT_OPT_NAME), &local_err); } else if (sn_id_or_name) { ret = bdrv_snapshot_load_tmp_by_id_or_name(bs, sn_id_or_name, &local_err); } if (ret < 0) { error_reportf_err(local_err, "Failed to load snapshot: "); exit(EXIT_FAILURE); } bs->detect_zeroes = detect_zeroes; fd_size = blk_getlength(blk); if (fd_size < 0) { error_report("Failed to determine the image length: %s", strerror(-fd_size)); exit(EXIT_FAILURE); } if (dev_offset >= fd_size) { error_report("Offset (%lld) has to be smaller than the image size " "(%lld)", (long long int)dev_offset, (long long int)fd_size); exit(EXIT_FAILURE); } fd_size -= dev_offset; if (partition != -1) { ret = find_partition(blk, partition, &dev_offset, &fd_size); if (ret < 0) { error_report("Could not find partition %d: %s", partition, strerror(-ret)); exit(EXIT_FAILURE); } } exp = nbd_export_new(bs, dev_offset, fd_size, nbdflags, nbd_export_closed, writethrough, NULL, &local_err); if (!exp) { error_report_err(local_err); exit(EXIT_FAILURE); } if (export_name) { nbd_export_set_name(exp, export_name); nbd_export_set_description(exp, export_description); newproto = true; } else if (export_description) { error_report("Export description requires an export name"); exit(EXIT_FAILURE); } if (device) { int ret; ret = pthread_create(&client_thread, NULL, nbd_client_thread, device); if (ret != 0) { error_report("Failed to create client thread: %s", strerror(ret)); exit(EXIT_FAILURE); } } else { /* Shut up GCC warnings. */ memset(&client_thread, 0, sizeof(client_thread)); } nbd_update_server_watch(); /* now when the initialization is (almost) complete, chdir("/") * to free any busy filesystems */ if (chdir("/") < 0) { error_report("Could not chdir to root directory: %s", strerror(errno)); exit(EXIT_FAILURE); } if (fork_process) { dup2(old_stderr, STDERR_FILENO); close(old_stderr); } state = RUNNING; do { main_loop_wait(false); if (state == TERMINATE) { state = TERMINATING; nbd_export_close(exp); nbd_export_put(exp); exp = NULL; } } while (state != TERMINATED); blk_unref(blk); if (sockpath) { unlink(sockpath); } qemu_opts_del(sn_opts); if (device) { void *ret; pthread_join(client_thread, &ret); exit(ret != NULL); } else { exit(EXIT_SUCCESS); } }
int main(int argc, char **argv) { int ret; g_assert(qcrypto_init(NULL) == 0); module_call_init(MODULE_INIT_QOM); g_test_init(&argc, &argv, NULL); setenv("GNUTLS_FORCE_FIPS_MODE", "2", 1); mkdir(WORKDIR, 0700); test_tls_init(KEYFILE); # define TEST_CHANNEL(name, caCrt, \ serverCrt, clientCrt, \ expectServerFail, expectClientFail, \ hostname, wildcards) \ struct QIOChannelTLSTestData name = { \ caCrt, caCrt, serverCrt, clientCrt, \ expectServerFail, expectClientFail, \ hostname, wildcards \ }; \ g_test_add_data_func("/qio/channel/tls/" # name, \ &name, test_io_channel_tls); /* A perfect CA, perfect client & perfect server */ /* Basic:CA:critical */ TLS_ROOT_REQ(cacertreq, "UK", "qemu CA", NULL, NULL, NULL, NULL, true, true, true, true, true, GNUTLS_KEY_KEY_CERT_SIGN, false, false, NULL, NULL, 0, 0); TLS_CERT_REQ(servercertreq, cacertreq, "UK", "qemu.org", NULL, NULL, NULL, NULL, true, true, false, true, true, GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT, true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL, 0, 0); TLS_CERT_REQ(clientcertreq, cacertreq, "UK", "qemu", NULL, NULL, NULL, NULL, true, true, false, true, true, GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT, true, true, GNUTLS_KP_TLS_WWW_CLIENT, NULL, 0, 0); const char *const wildcards[] = { "C=UK,CN=qemu*", NULL, }; TEST_CHANNEL(basic, cacertreq.filename, servercertreq.filename, clientcertreq.filename, false, false, "qemu.org", wildcards); ret = g_test_run(); test_tls_discard_cert(&clientcertreq); test_tls_discard_cert(&servercertreq); test_tls_discard_cert(&cacertreq); test_tls_cleanup(KEYFILE); rmdir(WORKDIR); return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; }
int main(int argc, char **argv) { const char *sopt = "hVvdm:p:l:f:b:s:t:"; const char *method = NULL, *path = NULL; const char *log_filepath = NULL; const char *pid_filepath = QGA_PIDFILE_DEFAULT; const char *state_dir = QGA_STATEDIR_DEFAULT; #ifdef _WIN32 const char *service = NULL; #endif const struct option lopt[] = { { "help", 0, NULL, 'h' }, { "version", 0, NULL, 'V' }, { "logfile", 1, NULL, 'l' }, { "pidfile", 1, NULL, 'f' }, { "verbose", 0, NULL, 'v' }, { "method", 1, NULL, 'm' }, { "path", 1, NULL, 'p' }, { "daemonize", 0, NULL, 'd' }, { "blacklist", 1, NULL, 'b' }, #ifdef _WIN32 { "service", 1, NULL, 's' }, #endif { "statedir", 1, NULL, 't' }, { NULL, 0, NULL, 0 } }; int opt_ind = 0, ch, daemonize = 0, i, j, len; GLogLevelFlags log_level = G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL; GList *blacklist = NULL; GAState *s; module_call_init(MODULE_INIT_QAPI); while ((ch = getopt_long(argc, argv, sopt, lopt, &opt_ind)) != -1) { switch (ch) { case 'm': method = optarg; break; case 'p': path = optarg; break; case 'l': log_filepath = optarg; break; case 'f': pid_filepath = optarg; break; case 't': state_dir = optarg; break; case 'v': /* enable all log levels */ log_level = G_LOG_LEVEL_MASK; break; case 'V': printf("QEMU Guest Agent %s\n", QEMU_VERSION); return 0; case 'd': daemonize = 1; break; case 'b': { char **list_head, **list; if (is_help_option(optarg)) { list_head = list = qmp_get_command_list(); while (*list != NULL) { printf("%s\n", *list); g_free(*list); list++; } g_free(list_head); return 0; } for (j = 0, i = 0, len = strlen(optarg); i < len; i++) { if (optarg[i] == ',') { optarg[i] = 0; blacklist = g_list_append(blacklist, &optarg[j]); j = i + 1; } } if (j < i) { blacklist = g_list_append(blacklist, &optarg[j]); } break; } #ifdef _WIN32 case 's': service = optarg; if (strcmp(service, "install") == 0) { return ga_install_service(path, log_filepath); } else if (strcmp(service, "uninstall") == 0) { return ga_uninstall_service(); } else { printf("Unknown service command.\n"); return EXIT_FAILURE; } break; #endif case 'h': usage(argv[0]); return 0; case '?': g_print("Unknown option, try '%s --help' for more information.\n", argv[0]); return EXIT_FAILURE; } } s = g_malloc0(sizeof(GAState)); s->log_level = log_level; s->log_file = stderr; g_log_set_default_handler(ga_log, s); g_log_set_fatal_mask(NULL, G_LOG_LEVEL_ERROR); ga_enable_logging(s); s->state_filepath_isfrozen = g_strdup_printf("%s/qga.state.isfrozen", state_dir); s->frozen = false; #ifndef _WIN32 /* check if a previous instance of qemu-ga exited with filesystems' state * marked as frozen. this could be a stale value (a non-qemu-ga process * or reboot may have since unfrozen them), but better to require an * uneeded unfreeze than to risk hanging on start-up */ struct stat st; if (stat(s->state_filepath_isfrozen, &st) == -1) { /* it's okay if the file doesn't exist, but if we can't access for * some other reason, such as permissions, there's a configuration * that needs to be addressed. so just bail now before we get into * more trouble later */ if (errno != ENOENT) { g_critical("unable to access state file at path %s: %s", s->state_filepath_isfrozen, strerror(errno)); return EXIT_FAILURE; } } else { g_warning("previous instance appears to have exited with frozen" " filesystems. deferring logging/pidfile creation and" " disabling non-fsfreeze-safe commands until" " guest-fsfreeze-thaw is issued, or filesystems are" " manually unfrozen and the file %s is removed", s->state_filepath_isfrozen); s->frozen = true; } #endif if (ga_is_frozen(s)) { if (daemonize) { /* delay opening/locking of pidfile till filesystem are unfrozen */ s->deferred_options.pid_filepath = pid_filepath; become_daemon(NULL); } if (log_filepath) { /* delay opening the log file till filesystems are unfrozen */ s->deferred_options.log_filepath = log_filepath; } ga_disable_logging(s); ga_disable_non_whitelisted(); } else { if (daemonize) { become_daemon(pid_filepath); } if (log_filepath) { FILE *log_file = fopen(log_filepath, "a"); if (!log_file) { g_critical("unable to open specified log file: %s", strerror(errno)); goto out_bad; } s->log_file = log_file; } } if (blacklist) { s->blacklist = blacklist; do { g_debug("disabling command: %s", (char *)blacklist->data); qmp_disable_command(blacklist->data); blacklist = g_list_next(blacklist); } while (blacklist); } s->command_state = ga_command_state_new(); ga_command_state_init(s, s->command_state); ga_command_state_init_all(s->command_state); json_message_parser_init(&s->parser, process_event); ga_state = s; #ifndef _WIN32 if (!register_signal_handlers()) { g_critical("failed to register signal handlers"); goto out_bad; } #endif s->main_loop = g_main_loop_new(NULL, false); if (!channel_init(ga_state, method, path)) { g_critical("failed to initialize guest agent channel"); goto out_bad; } #ifndef _WIN32 g_main_loop_run(ga_state->main_loop); #else if (daemonize) { SERVICE_TABLE_ENTRY service_table[] = { { (char *)QGA_SERVICE_NAME, service_main }, { NULL, NULL } }; StartServiceCtrlDispatcher(service_table); } else { g_main_loop_run(ga_state->main_loop); } #endif ga_command_state_cleanup_all(ga_state->command_state); ga_channel_free(ga_state->channel); if (daemonize) { unlink(pid_filepath); } return 0; out_bad: if (daemonize) { unlink(pid_filepath); } return EXIT_FAILURE; }
int main(int argc, char **argv) { int ret; module_call_init(MODULE_INIT_QOM); g_test_init(&argc, &argv, NULL); setenv("GNUTLS_FORCE_FIPS_MODE", "2", 1); mkdir(WORKDIR, 0700); test_tls_init(KEYFILE); # define TLS_TEST_REG(name, isServer, caCrt, crt, expectFail) \ struct QCryptoTLSCredsTestData name = { \ isServer, caCrt, crt, expectFail \ }; \ g_test_add_data_func("/qcrypto/tlscredsx509/" # name, \ &name, test_tls_creds); \ /* A perfect CA, perfect client & perfect server */ /* Basic:CA:critical */ TLS_ROOT_REQ(cacertreq, "UK", "qemu CA", NULL, NULL, NULL, NULL, true, true, true, true, true, GNUTLS_KEY_KEY_CERT_SIGN, false, false, NULL, NULL, 0, 0); TLS_CERT_REQ(servercertreq, cacertreq, "UK", "qemu.org", NULL, NULL, NULL, NULL, true, true, false, true, true, GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT, true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL, 0, 0); TLS_CERT_REQ(clientcertreq, cacertreq, "UK", "qemu", NULL, NULL, NULL, NULL, true, true, false, true, true, GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT, true, true, GNUTLS_KP_TLS_WWW_CLIENT, NULL, 0, 0); TLS_TEST_REG(perfectserver, true, cacertreq.filename, servercertreq.filename, false); TLS_TEST_REG(perfectclient, false, cacertreq.filename, clientcertreq.filename, false); /* Some other CAs which are good */ /* Basic:CA:critical */ TLS_ROOT_REQ(cacert1req, "UK", "qemu CA 1", NULL, NULL, NULL, NULL, true, true, true, false, false, 0, false, false, NULL, NULL, 0, 0); TLS_CERT_REQ(servercert1req, cacert1req, "UK", "qemu.org", NULL, NULL, NULL, NULL, true, true, false, true, true, GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT, true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL, 0, 0); /* Basic:CA:not-critical */ TLS_ROOT_REQ(cacert2req, "UK", "qemu CA 2", NULL, NULL, NULL, NULL, true, false, true, false, false, 0, false, false, NULL, NULL, 0, 0); TLS_CERT_REQ(servercert2req, cacert2req, "UK", "qemu.org", NULL, NULL, NULL, NULL, true, true, false, true, true, GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT, true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL, 0, 0); /* Key usage:cert-sign:critical */ TLS_ROOT_REQ(cacert3req, "UK", "qemu CA 3", NULL, NULL, NULL, NULL, true, true, true, true, true, GNUTLS_KEY_KEY_CERT_SIGN, false, false, NULL, NULL, 0, 0); TLS_CERT_REQ(servercert3req, cacert3req, "UK", "qemu.org", NULL, NULL, NULL, NULL, true, true, false, true, true, GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT, true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL, 0, 0); TLS_TEST_REG(goodca1, true, cacert1req.filename, servercert1req.filename, false); TLS_TEST_REG(goodca2, true, cacert2req.filename, servercert2req.filename, false); TLS_TEST_REG(goodca3, true, cacert3req.filename, servercert3req.filename, false); /* Now some bad certs */ /* Key usage:dig-sig:not-critical */ TLS_ROOT_REQ(cacert4req, "UK", "qemu CA 4", NULL, NULL, NULL, NULL, true, true, true, true, false, GNUTLS_KEY_DIGITAL_SIGNATURE, false, false, NULL, NULL, 0, 0); TLS_CERT_REQ(servercert4req, cacert4req, "UK", "qemu.org", NULL, NULL, NULL, NULL, true, true, false, true, true, GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT, true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL, 0, 0); /* no-basic */ TLS_ROOT_REQ(cacert5req, "UK", "qemu CA 5", NULL, NULL, NULL, NULL, false, false, false, false, false, 0, false, false, NULL, NULL, 0, 0); TLS_CERT_REQ(servercert5req, cacert5req, "UK", "qemu.org", NULL, NULL, NULL, NULL, true, true, false, true, true, GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT, true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL, 0, 0); /* Key usage:dig-sig:critical */ TLS_ROOT_REQ(cacert6req, "UK", "qemu CA 6", NULL, NULL, NULL, NULL, true, true, true, true, true, GNUTLS_KEY_DIGITAL_SIGNATURE, false, false, NULL, NULL, 0, 0); TLS_CERT_REQ(servercert6req, cacert6req, "UK", "qemu.org", NULL, NULL, NULL, NULL, true, true, false, true, true, GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT, true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL, 0, 0); /* Technically a CA cert with basic constraints * key purpose == key signing + non-critical should * be rejected. GNUTLS < 3.1 does not reject it and * we don't anticipate them changing this behaviour */ TLS_TEST_REG(badca1, true, cacert4req.filename, servercert4req.filename, (GNUTLS_VERSION_MAJOR == 3 && GNUTLS_VERSION_MINOR >= 1) || GNUTLS_VERSION_MAJOR > 3); TLS_TEST_REG(badca2, true, cacert5req.filename, servercert5req.filename, true); TLS_TEST_REG(badca3, true, cacert6req.filename, servercert6req.filename, true); /* Various good servers */ /* no usage or purpose */ TLS_CERT_REQ(servercert7req, cacertreq, "UK", "qemu", NULL, NULL, NULL, NULL, true, true, false, false, false, 0, false, false, NULL, NULL, 0, 0); /* usage:cert-sign+dig-sig+encipher:critical */ TLS_CERT_REQ(servercert8req, cacertreq, "UK", "qemu", NULL, NULL, NULL, NULL, true, true, false, true, true, GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT | GNUTLS_KEY_KEY_CERT_SIGN, false, false, NULL, NULL, 0, 0); /* usage:cert-sign:not-critical */ TLS_CERT_REQ(servercert9req, cacertreq, "UK", "qemu", NULL, NULL, NULL, NULL, true, true, false, true, false, GNUTLS_KEY_KEY_CERT_SIGN, false, false, NULL, NULL, 0, 0); /* purpose:server:critical */ TLS_CERT_REQ(servercert10req, cacertreq, "UK", "qemu", NULL, NULL, NULL, NULL, true, true, false, false, false, 0, true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL, 0, 0); /* purpose:server:not-critical */ TLS_CERT_REQ(servercert11req, cacertreq, "UK", "qemu", NULL, NULL, NULL, NULL, true, true, false, false, false, 0, true, false, GNUTLS_KP_TLS_WWW_SERVER, NULL, 0, 0); /* purpose:client+server:critical */ TLS_CERT_REQ(servercert12req, cacertreq, "UK", "qemu", NULL, NULL, NULL, NULL, true, true, false, false, false, 0, true, true, GNUTLS_KP_TLS_WWW_CLIENT, GNUTLS_KP_TLS_WWW_SERVER, 0, 0); /* purpose:client+server:not-critical */ TLS_CERT_REQ(servercert13req, cacertreq, "UK", "qemu", NULL, NULL, NULL, NULL, true, true, false, false, false, 0, true, false, GNUTLS_KP_TLS_WWW_CLIENT, GNUTLS_KP_TLS_WWW_SERVER, 0, 0); TLS_TEST_REG(goodserver1, true, cacertreq.filename, servercert7req.filename, false); TLS_TEST_REG(goodserver2, true, cacertreq.filename, servercert8req.filename, false); TLS_TEST_REG(goodserver3, true, cacertreq.filename, servercert9req.filename, false); TLS_TEST_REG(goodserver4, true, cacertreq.filename, servercert10req.filename, false); TLS_TEST_REG(goodserver5, true, cacertreq.filename, servercert11req.filename, false); TLS_TEST_REG(goodserver6, true, cacertreq.filename, servercert12req.filename, false); TLS_TEST_REG(goodserver7, true, cacertreq.filename, servercert13req.filename, false); /* Bad servers */ /* usage:cert-sign:critical */ TLS_CERT_REQ(servercert14req, cacertreq, "UK", "qemu", NULL, NULL, NULL, NULL, true, true, false, true, true, GNUTLS_KEY_KEY_CERT_SIGN, false, false, NULL, NULL, 0, 0); /* purpose:client:critical */ TLS_CERT_REQ(servercert15req, cacertreq, "UK", "qemu", NULL, NULL, NULL, NULL, true, true, false, false, false, 0, true, true, GNUTLS_KP_TLS_WWW_CLIENT, NULL, 0, 0); /* usage: none:critical */ TLS_CERT_REQ(servercert16req, cacertreq, "UK", "qemu", NULL, NULL, NULL, NULL, true, true, false, true, true, 0, false, false, NULL, NULL, 0, 0); TLS_TEST_REG(badserver1, true, cacertreq.filename, servercert14req.filename, true); TLS_TEST_REG(badserver2, true, cacertreq.filename, servercert15req.filename, true); TLS_TEST_REG(badserver3, true, cacertreq.filename, servercert16req.filename, true); /* Various good clients */ /* no usage or purpose */ TLS_CERT_REQ(clientcert1req, cacertreq, "UK", "qemu", NULL, NULL, NULL, NULL, true, true, false, false, false, 0, false, false, NULL, NULL, 0, 0); /* usage:cert-sign+dig-sig+encipher:critical */ TLS_CERT_REQ(clientcert2req, cacertreq, "UK", "qemu", NULL, NULL, NULL, NULL, true, true, false, true, true, GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT | GNUTLS_KEY_KEY_CERT_SIGN, false, false, NULL, NULL, 0, 0); /* usage:cert-sign:not-critical */ TLS_CERT_REQ(clientcert3req, cacertreq, "UK", "qemu", NULL, NULL, NULL, NULL, true, true, false, true, false, GNUTLS_KEY_KEY_CERT_SIGN, false, false, NULL, NULL, 0, 0); /* purpose:client:critical */ TLS_CERT_REQ(clientcert4req, cacertreq, "UK", "qemu", NULL, NULL, NULL, NULL, true, true, false, false, false, 0, true, true, GNUTLS_KP_TLS_WWW_CLIENT, NULL, 0, 0); /* purpose:client:not-critical */ TLS_CERT_REQ(clientcert5req, cacertreq, "UK", "qemu", NULL, NULL, NULL, NULL, true, true, false, false, false, 0, true, false, GNUTLS_KP_TLS_WWW_CLIENT, NULL, 0, 0); /* purpose:client+client:critical */ TLS_CERT_REQ(clientcert6req, cacertreq, "UK", "qemu", NULL, NULL, NULL, NULL, true, true, false, false, false, 0, true, true, GNUTLS_KP_TLS_WWW_CLIENT, GNUTLS_KP_TLS_WWW_SERVER, 0, 0); /* purpose:client+client:not-critical */ TLS_CERT_REQ(clientcert7req, cacertreq, "UK", "qemu", NULL, NULL, NULL, NULL, true, true, false, false, false, 0, true, false, GNUTLS_KP_TLS_WWW_CLIENT, GNUTLS_KP_TLS_WWW_SERVER, 0, 0); TLS_TEST_REG(goodclient1, false, cacertreq.filename, clientcert1req.filename, false); TLS_TEST_REG(goodclient2, false, cacertreq.filename, clientcert2req.filename, false); TLS_TEST_REG(goodclient3, false, cacertreq.filename, clientcert3req.filename, false); TLS_TEST_REG(goodclient4, false, cacertreq.filename, clientcert4req.filename, false); TLS_TEST_REG(goodclient5, false, cacertreq.filename, clientcert5req.filename, false); TLS_TEST_REG(goodclient6, false, cacertreq.filename, clientcert6req.filename, false); TLS_TEST_REG(goodclient7, false, cacertreq.filename, clientcert7req.filename, false); /* Bad clients */ /* usage:cert-sign:critical */ TLS_CERT_REQ(clientcert8req, cacertreq, "UK", "qemu", NULL, NULL, NULL, NULL, true, true, false, true, true, GNUTLS_KEY_KEY_CERT_SIGN, false, false, NULL, NULL, 0, 0); /* purpose:client:critical */ TLS_CERT_REQ(clientcert9req, cacertreq, "UK", "qemu", NULL, NULL, NULL, NULL, true, true, false, false, false, 0, true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL, 0, 0); /* usage: none:critical */ TLS_CERT_REQ(clientcert10req, cacertreq, "UK", "qemu", NULL, NULL, NULL, NULL, true, true, false, true, true, 0, false, false, NULL, NULL, 0, 0); TLS_TEST_REG(badclient1, false, cacertreq.filename, clientcert8req.filename, true); TLS_TEST_REG(badclient2, false, cacertreq.filename, clientcert9req.filename, true); TLS_TEST_REG(badclient3, false, cacertreq.filename, clientcert10req.filename, true); /* Expired stuff */ TLS_ROOT_REQ(cacertexpreq, "UK", "qemu", NULL, NULL, NULL, NULL, true, true, true, true, true, GNUTLS_KEY_KEY_CERT_SIGN, false, false, NULL, NULL, 0, -1); TLS_CERT_REQ(servercertexpreq, cacertexpreq, "UK", "qemu.org", NULL, NULL, NULL, NULL, true, true, false, true, true, GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT, true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL, 0, 0); TLS_CERT_REQ(servercertexp1req, cacertreq, "UK", "qemu", NULL, NULL, NULL, NULL, true, true, false, true, true, GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT, true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL, 0, -1); TLS_CERT_REQ(clientcertexp1req, cacertreq, "UK", "qemu", NULL, NULL, NULL, NULL, true, true, false, true, true, GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT, true, true, GNUTLS_KP_TLS_WWW_CLIENT, NULL, 0, -1); TLS_TEST_REG(expired1, true, cacertexpreq.filename, servercertexpreq.filename, true); TLS_TEST_REG(expired2, true, cacertreq.filename, servercertexp1req.filename, true); TLS_TEST_REG(expired3, false, cacertreq.filename, clientcertexp1req.filename, true); /* Not activated stuff */ TLS_ROOT_REQ(cacertnewreq, "UK", "qemu", NULL, NULL, NULL, NULL, true, true, true, true, true, GNUTLS_KEY_KEY_CERT_SIGN, false, false, NULL, NULL, 1, 2); TLS_CERT_REQ(servercertnewreq, cacertnewreq, "UK", "qemu", NULL, NULL, NULL, NULL, true, true, false, true, true, GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT, true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL, 0, 0); TLS_CERT_REQ(servercertnew1req, cacertreq, "UK", "qemu", NULL, NULL, NULL, NULL, true, true, false, true, true, GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT, true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL, 1, 2); TLS_CERT_REQ(clientcertnew1req, cacertreq, "UK", "qemu", NULL, NULL, NULL, NULL, true, true, false, true, true, GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT, true, true, GNUTLS_KP_TLS_WWW_CLIENT, NULL, 1, 2); TLS_TEST_REG(inactive1, true, cacertnewreq.filename, servercertnewreq.filename, true); TLS_TEST_REG(inactive2, true, cacertreq.filename, servercertnew1req.filename, true); TLS_TEST_REG(inactive3, false, cacertreq.filename, clientcertnew1req.filename, true); TLS_ROOT_REQ(cacertrootreq, "UK", "qemu root", NULL, NULL, NULL, NULL, true, true, true, true, true, GNUTLS_KEY_KEY_CERT_SIGN, false, false, NULL, NULL, 0, 0); TLS_CERT_REQ(cacertlevel1areq, cacertrootreq, "UK", "qemu level 1a", NULL, NULL, NULL, NULL, true, true, true, true, true, GNUTLS_KEY_KEY_CERT_SIGN, false, false, NULL, NULL, 0, 0); TLS_CERT_REQ(cacertlevel1breq, cacertrootreq, "UK", "qemu level 1b", NULL, NULL, NULL, NULL, true, true, true, true, true, GNUTLS_KEY_KEY_CERT_SIGN, false, false, NULL, NULL, 0, 0); TLS_CERT_REQ(cacertlevel2areq, cacertlevel1areq, "UK", "qemu level 2a", NULL, NULL, NULL, NULL, true, true, true, true, true, GNUTLS_KEY_KEY_CERT_SIGN, false, false, NULL, NULL, 0, 0); TLS_CERT_REQ(servercertlevel3areq, cacertlevel2areq, "UK", "qemu.org", NULL, NULL, NULL, NULL, true, true, false, true, true, GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT, true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL, 0, 0); TLS_CERT_REQ(clientcertlevel2breq, cacertlevel1breq, "UK", "qemu client level 2b", NULL, NULL, NULL, NULL, true, true, false, true, true, GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT, true, true, GNUTLS_KP_TLS_WWW_CLIENT, NULL, 0, 0); gnutls_x509_crt_t certchain[] = { cacertrootreq.crt, cacertlevel1areq.crt, cacertlevel1breq.crt, cacertlevel2areq.crt, }; test_tls_write_cert_chain(WORKDIR "cacertchain-ctx.pem", certchain, G_N_ELEMENTS(certchain)); TLS_TEST_REG(chain1, true, WORKDIR "cacertchain-ctx.pem", servercertlevel3areq.filename, false); TLS_TEST_REG(chain2, false, WORKDIR "cacertchain-ctx.pem", clientcertlevel2breq.filename, false); /* Some missing certs - first two are fatal, the last * is ok */ TLS_TEST_REG(missingca, true, "cacertdoesnotexist.pem", servercert1req.filename, true); TLS_TEST_REG(missingserver, true, cacert1req.filename, "servercertdoesnotexist.pem", true); TLS_TEST_REG(missingclient, false, cacert1req.filename, "clientcertdoesnotexist.pem", false); ret = g_test_run(); test_tls_discard_cert(&cacertreq); test_tls_discard_cert(&cacert1req); test_tls_discard_cert(&cacert2req); test_tls_discard_cert(&cacert3req); test_tls_discard_cert(&cacert4req); test_tls_discard_cert(&cacert5req); test_tls_discard_cert(&cacert6req); test_tls_discard_cert(&servercertreq); test_tls_discard_cert(&servercert1req); test_tls_discard_cert(&servercert2req); test_tls_discard_cert(&servercert3req); test_tls_discard_cert(&servercert4req); test_tls_discard_cert(&servercert5req); test_tls_discard_cert(&servercert6req); test_tls_discard_cert(&servercert7req); test_tls_discard_cert(&servercert8req); test_tls_discard_cert(&servercert9req); test_tls_discard_cert(&servercert10req); test_tls_discard_cert(&servercert11req); test_tls_discard_cert(&servercert12req); test_tls_discard_cert(&servercert13req); test_tls_discard_cert(&servercert14req); test_tls_discard_cert(&servercert15req); test_tls_discard_cert(&servercert16req); test_tls_discard_cert(&clientcertreq); test_tls_discard_cert(&clientcert1req); test_tls_discard_cert(&clientcert2req); test_tls_discard_cert(&clientcert3req); test_tls_discard_cert(&clientcert4req); test_tls_discard_cert(&clientcert5req); test_tls_discard_cert(&clientcert6req); test_tls_discard_cert(&clientcert7req); test_tls_discard_cert(&clientcert8req); test_tls_discard_cert(&clientcert9req); test_tls_discard_cert(&clientcert10req); test_tls_discard_cert(&cacertexpreq); test_tls_discard_cert(&servercertexpreq); test_tls_discard_cert(&servercertexp1req); test_tls_discard_cert(&clientcertexp1req); test_tls_discard_cert(&cacertnewreq); test_tls_discard_cert(&servercertnewreq); test_tls_discard_cert(&servercertnew1req); test_tls_discard_cert(&clientcertnew1req); test_tls_discard_cert(&cacertrootreq); test_tls_discard_cert(&cacertlevel1areq); test_tls_discard_cert(&cacertlevel1breq); test_tls_discard_cert(&cacertlevel2areq); test_tls_discard_cert(&servercertlevel3areq); test_tls_discard_cert(&clientcertlevel2breq); unlink(WORKDIR "cacertchain-ctx.pem"); test_tls_cleanup(KEYFILE); rmdir(WORKDIR); return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; }