OSCommandLine::OSCommandLine(): osinstance(NULL), osoption(NULL) { #ifdef DEBUG_COMMANDLINE std::cout << "Inside command line constructor" << std::endl; #endif reset_options(); }
main() { mach_port_t bootstrap_port; int i; struct test_dir *td, **tds; int all; kern_return_t kr; boolean_t found; int argc = 0; char **argv; MACH_CALL(task_get_special_port, (mach_task_self(), TASK_BOOTSTRAP_PORT, &bootstrap_port)); MACH_CALL(bootstrap_ports, (bootstrap_port, &privileged_host_port, &master_device_port, &root_ledger_wired, &root_ledger_paged, &security_port)); MACH_FUNC(host_port, mach_host_self, ()); standalone = is_standalone(); threads_init(); console_init(); _printf_init(); exception_init(); printf("\n\n"); version(); kernel_version(); if (standalone) printf("Standalone mode\n\n"); vm_opt = 1; print_vm_stats(); printf("\n"); get_thread_sched_attr(mach_thread_self(), (policy_state_t) 0, TRUE); printf("\n"); while(1) { mach_setjmp(&sa_jmp_buf); reset_options(); /* synthetic benchmarks are not the default type */ synthetic_fn = NULL; reset_more(); if (!(argc = read_cmd(&argv, "mpts> "))) continue; for (i = 1; i < argc; i++) is_gen_opt(argc, argv, &i, 0, 0); if (!strcmp(argv[0],"on")) { shift_args(&argc, argv); if (remote_node(argc, argv)) { shift_args(&argc, argv); } else { interruptible_cmd(usage, 0, 0); continue; } } if (!strcmp(argv[0],"more")) { shift_args(&argc, argv); } else disable_more(); all = strcmp(argv[0],"*") ? 0 : 1; for (found = FALSE, tds = test_dirs; *tds && !found; tds++) for (td = *tds; td->name && !found; td++) if ((all && td->is_a_test) || !strcmp(argv[0],td->name)) { if (td->is_a_test) printf("_______________________________________________________________________________\n"); argv[0] = td->name; if (td->is_a_test) interruptible_cmd(td->func, argc, argv); else (*td->func) (argc, argv); if (!all) found = TRUE; } if ((!all) && (!found)) { if (find_proc(argv[0])) /* run synthetic benchmark if we have a proc name */ interruptible_cmd(synthetic,argc,argv); else interruptible_cmd(usage, 0, 0); } } printf("done\n"); }
/* Test that single onion poisoning works. */ static void test_single_onion_poisoning(void *arg) { or_options_t opt; mock_options = &opt; reset_options(mock_options, &mock_get_options_calls); MOCK(get_options, mock_get_options); int ret = -1; intptr_t create_dir_mask = (intptr_t)arg; /* Get directories with a random suffix so we can repeat the tests */ mock_options->DataDirectory = tor_strdup(get_fname_rnd("test_data_dir")); rend_service_t *service_1 = tor_malloc_zero(sizeof(rend_service_t)); char *dir1 = tor_strdup(get_fname_rnd("test_hs_dir1")); rend_service_t *service_2 = tor_malloc_zero(sizeof(rend_service_t)); char *dir2 = tor_strdup(get_fname_rnd("test_hs_dir2")); smartlist_t *services = smartlist_new(); char *poison_path = NULL; char *err_msg = NULL; mock_options->HiddenServiceSingleHopMode = 1; mock_options->HiddenServiceNonAnonymousMode = 1; /* Create the data directory, and, if the correct bit in arg is set, * create a directory for that service. * The data directory is required for the lockfile, which is used when * loading keys. */ ret = check_private_dir(mock_options->DataDirectory, CPD_CREATE, NULL); tt_int_op(ret, OP_EQ, 0); if (create_dir_mask & CREATE_HS_DIR1) { ret = check_private_dir(dir1, CPD_CREATE, NULL); tt_int_op(ret, OP_EQ, 0); } if (create_dir_mask & CREATE_HS_DIR2) { ret = check_private_dir(dir2, CPD_CREATE, NULL); tt_int_op(ret, OP_EQ, 0); } service_1->directory = dir1; service_2->directory = dir2; /* The services own the directory pointers now */ dir1 = dir2 = NULL; /* Add port to service 1 */ service_1->ports = smartlist_new(); service_2->ports = smartlist_new(); rend_service_port_config_t *port1 = rend_service_parse_port_config("80", " ", &err_msg); tt_assert(port1); tt_ptr_op(err_msg, OP_EQ, NULL); smartlist_add(service_1->ports, port1); rend_service_port_config_t *port2 = rend_service_parse_port_config("90", " ", &err_msg); /* Add port to service 2 */ tt_assert(port2); tt_ptr_op(err_msg, OP_EQ, NULL); smartlist_add(service_2->ports, port2); /* No services, a service to verify, no problem! */ mock_options->HiddenServiceSingleHopMode = 0; mock_options->HiddenServiceNonAnonymousMode = 0; ret = rend_service_verify_single_onion_poison(service_1, mock_options); tt_int_op(ret, OP_EQ, 0); ret = rend_service_verify_single_onion_poison(service_2, mock_options); tt_int_op(ret, OP_EQ, 0); /* Either way, no problem. */ mock_options->HiddenServiceSingleHopMode = 1; mock_options->HiddenServiceNonAnonymousMode = 1; ret = rend_service_verify_single_onion_poison(service_1, mock_options); tt_int_op(ret, OP_EQ, 0); ret = rend_service_verify_single_onion_poison(service_2, mock_options); tt_int_op(ret, OP_EQ, 0); /* Add the first service */ ret = hs_check_service_private_dir(mock_options->User, service_1->directory, service_1->dir_group_readable, 1); tt_int_op(ret, OP_EQ, 0); smartlist_add(services, service_1); /* But don't add the second service yet. */ /* Service directories, but no previous keys, no problem! */ mock_options->HiddenServiceSingleHopMode = 0; mock_options->HiddenServiceNonAnonymousMode = 0; ret = rend_service_verify_single_onion_poison(service_1, mock_options); tt_int_op(ret, OP_EQ, 0); ret = rend_service_verify_single_onion_poison(service_2, mock_options); tt_int_op(ret, OP_EQ, 0); /* Either way, no problem. */ mock_options->HiddenServiceSingleHopMode = 1; mock_options->HiddenServiceNonAnonymousMode = 1; ret = rend_service_verify_single_onion_poison(service_1, mock_options); tt_int_op(ret, OP_EQ, 0); ret = rend_service_verify_single_onion_poison(service_2, mock_options); tt_int_op(ret, OP_EQ, 0); /* Poison! Poison! Poison! * This can only be done in HiddenServiceSingleHopMode. */ mock_options->HiddenServiceSingleHopMode = 1; mock_options->HiddenServiceNonAnonymousMode = 1; ret = rend_service_poison_new_single_onion_dir(service_1, mock_options); tt_int_op(ret, OP_EQ, 0); /* Poisoning twice is a no-op. */ ret = rend_service_poison_new_single_onion_dir(service_1, mock_options); tt_int_op(ret, OP_EQ, 0); /* Poisoned service directories, but no previous keys, no problem! */ mock_options->HiddenServiceSingleHopMode = 0; mock_options->HiddenServiceNonAnonymousMode = 0; ret = rend_service_verify_single_onion_poison(service_1, mock_options); tt_int_op(ret, OP_EQ, 0); ret = rend_service_verify_single_onion_poison(service_2, mock_options); tt_int_op(ret, OP_EQ, 0); /* Either way, no problem. */ mock_options->HiddenServiceSingleHopMode = 1; mock_options->HiddenServiceNonAnonymousMode = 1; ret = rend_service_verify_single_onion_poison(service_1, mock_options); tt_int_op(ret, OP_EQ, 0); ret = rend_service_verify_single_onion_poison(service_2, mock_options); tt_int_op(ret, OP_EQ, 0); /* Now add some keys, and we'll have a problem. */ ret = rend_service_load_all_keys(services); tt_int_op(ret, OP_EQ, 0); /* Poisoned service directories with previous keys are not allowed. */ mock_options->HiddenServiceSingleHopMode = 0; mock_options->HiddenServiceNonAnonymousMode = 0; ret = rend_service_verify_single_onion_poison(service_1, mock_options); tt_int_op(ret, OP_LT, 0); ret = rend_service_verify_single_onion_poison(service_2, mock_options); tt_int_op(ret, OP_EQ, 0); /* But they are allowed if we're in non-anonymous mode. */ mock_options->HiddenServiceSingleHopMode = 1; mock_options->HiddenServiceNonAnonymousMode = 1; ret = rend_service_verify_single_onion_poison(service_1, mock_options); tt_int_op(ret, OP_EQ, 0); ret = rend_service_verify_single_onion_poison(service_2, mock_options); tt_int_op(ret, OP_EQ, 0); /* Re-poisoning directories with existing keys is a no-op, because * directories with existing keys are ignored. */ mock_options->HiddenServiceSingleHopMode = 1; mock_options->HiddenServiceNonAnonymousMode = 1; ret = rend_service_poison_new_single_onion_dir(service_1, mock_options); tt_int_op(ret, OP_EQ, 0); /* And it keeps the poison. */ ret = rend_service_verify_single_onion_poison(service_1, mock_options); tt_int_op(ret, OP_EQ, 0); ret = rend_service_verify_single_onion_poison(service_2, mock_options); tt_int_op(ret, OP_EQ, 0); /* Now add the second service: it has no key and no poison file */ ret = hs_check_service_private_dir(mock_options->User, service_2->directory, service_2->dir_group_readable, 1); tt_int_op(ret, OP_EQ, 0); smartlist_add(services, service_2); /* A new service, and an existing poisoned service. Not ok. */ mock_options->HiddenServiceSingleHopMode = 0; mock_options->HiddenServiceNonAnonymousMode = 0; ret = rend_service_verify_single_onion_poison(service_1, mock_options); tt_int_op(ret, OP_LT, 0); ret = rend_service_verify_single_onion_poison(service_2, mock_options); tt_int_op(ret, OP_EQ, 0); /* But ok to add in non-anonymous mode. */ mock_options->HiddenServiceSingleHopMode = 1; mock_options->HiddenServiceNonAnonymousMode = 1; ret = rend_service_verify_single_onion_poison(service_1, mock_options); tt_int_op(ret, OP_EQ, 0); ret = rend_service_verify_single_onion_poison(service_2, mock_options); tt_int_op(ret, OP_EQ, 0); /* Now remove the poisoning from the first service, and we have the opposite * problem. */ poison_path = rend_service_sos_poison_path(service_1); tt_assert(poison_path); ret = unlink(poison_path); tt_int_op(ret, OP_EQ, 0); /* Unpoisoned service directories with previous keys are ok, as are empty * directories. */ mock_options->HiddenServiceSingleHopMode = 0; mock_options->HiddenServiceNonAnonymousMode = 0; ret = rend_service_verify_single_onion_poison(service_1, mock_options); tt_int_op(ret, OP_EQ, 0); ret = rend_service_verify_single_onion_poison(service_2, mock_options); tt_int_op(ret, OP_EQ, 0); /* But the existing unpoisoned key is not ok in non-anonymous mode, even if * there is an empty service. */ mock_options->HiddenServiceSingleHopMode = 1; mock_options->HiddenServiceNonAnonymousMode = 1; ret = rend_service_verify_single_onion_poison(service_1, mock_options); tt_int_op(ret, OP_LT, 0); ret = rend_service_verify_single_onion_poison(service_2, mock_options); tt_int_op(ret, OP_EQ, 0); /* Poisoning directories with existing keys is a no-op, because directories * with existing keys are ignored. But the new directory should poison. */ mock_options->HiddenServiceSingleHopMode = 1; mock_options->HiddenServiceNonAnonymousMode = 1; ret = rend_service_poison_new_single_onion_dir(service_1, mock_options); tt_int_op(ret, OP_EQ, 0); ret = rend_service_poison_new_single_onion_dir(service_2, mock_options); tt_int_op(ret, OP_EQ, 0); /* And the old directory remains unpoisoned. */ ret = rend_service_verify_single_onion_poison(service_1, mock_options); tt_int_op(ret, OP_LT, 0); ret = rend_service_verify_single_onion_poison(service_2, mock_options); tt_int_op(ret, OP_EQ, 0); /* And the new directory should be ignored, because it has no key. */ mock_options->HiddenServiceSingleHopMode = 0; mock_options->HiddenServiceNonAnonymousMode = 0; ret = rend_service_verify_single_onion_poison(service_1, mock_options); tt_int_op(ret, OP_EQ, 0); ret = rend_service_verify_single_onion_poison(service_2, mock_options); tt_int_op(ret, OP_EQ, 0); /* Re-poisoning directories without existing keys is a no-op. */ mock_options->HiddenServiceSingleHopMode = 1; mock_options->HiddenServiceNonAnonymousMode = 1; ret = rend_service_poison_new_single_onion_dir(service_1, mock_options); tt_int_op(ret, OP_EQ, 0); ret = rend_service_poison_new_single_onion_dir(service_2, mock_options); tt_int_op(ret, OP_EQ, 0); /* And the old directory remains unpoisoned. */ ret = rend_service_verify_single_onion_poison(service_1, mock_options); tt_int_op(ret, OP_LT, 0); ret = rend_service_verify_single_onion_poison(service_2, mock_options); tt_int_op(ret, OP_EQ, 0); done: /* The test harness deletes the directories at exit */ tor_free(poison_path); tor_free(dir1); tor_free(dir2); smartlist_free(services); rend_service_free(service_1); rend_service_free(service_2); UNMOCK(get_options); tor_free(mock_options->DataDirectory); tor_free(err_msg); }
/* Test iterators. */ int main(int argc, char *argv[]) { unsigned j, i, len = 0; const char *p; plan_tests(37 * 2); for (j = 0; j < 2; j ++) { reset_options(); /* Giving subtable a title makes an extra entry! */ opt_register_table(subtables, j == 0 ? NULL : "subtable"); p = first_lopt(&i, &len); ok1(i == j + 0); ok1(len == 3); ok1(strncmp(p, "jjj", len) == 0); p = next_lopt(p, &i, &len); ok1(i == j + 0); ok1(len == 3); ok1(strncmp(p, "lll", len) == 0); p = next_lopt(p, &i, &len); ok1(i == j + 1); ok1(len == 3); ok1(strncmp(p, "mmm", len) == 0); p = next_lopt(p, &i, &len); ok1(i == j + 5); ok1(len == 3); ok1(strncmp(p, "ddd", len) == 0); p = next_lopt(p, &i, &len); ok1(i == j + 6); ok1(len == 3); ok1(strncmp(p, "eee", len) == 0); p = next_lopt(p, &i, &len); ok1(i == j + 7); ok1(len == 3); ok1(strncmp(p, "ggg", len) == 0); p = next_lopt(p, &i, &len); ok1(i == j + 8); ok1(len == 3); ok1(strncmp(p, "hhh", len) == 0); p = next_lopt(p, &i, &len); ok1(!p); p = first_sopt(&i); ok1(i == j + 0); ok1(*p == 'j'); p = next_sopt(p, &i); ok1(i == j + 0); ok1(*p == 'l'); p = next_sopt(p, &i); ok1(i == j + 1); ok1(*p == 'm'); p = next_sopt(p, &i); ok1(i == j + 2); ok1(*p == 'a'); p = next_sopt(p, &i); ok1(i == j + 3); ok1(*p == 'b'); p = next_sopt(p, &i); ok1(i == j + 7); ok1(*p == 'g'); p = next_sopt(p, &i); ok1(i == j + 8); ok1(*p == 'h'); p = next_sopt(p, &i); ok1(!p); } return exit_status(); }
/* Test helpers. */ int main(int argc, char *argv[]) { char *output; char *longname = strdup("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); char *shortname = strdup("shortname"); plan_tests(48); opt_register_table(subtables, NULL); opt_register_noarg("--kkk|-k", my_cb, NULL, "magic kkk option"); opt_register_noarg("-?", opt_usage_and_exit, "<MyArgs>...", "This message"); opt_register_arg("--longname", opt_set_charp, opt_show_charp, &longname, "a really long option default"); opt_register_arg("--shortname", opt_set_charp, opt_show_charp, &shortname, "a short option default"); output = opt_usage("my name", "ExTrA Args"); diag("%s", output); ok1(strstr(output, "Usage: my name")); ok1(strstr(output, "--jjj|-j|--lll|-l <arg>")); ok1(strstr(output, "ExTrA Args")); ok1(strstr(output, "-a ")); ok1(strstr(output, " Description of a\n")); ok1(strstr(output, "-b <arg>")); ok1(strstr(output, " Description of b (default: b)\n")); ok1(strstr(output, "--ddd ")); ok1(strstr(output, " Description of ddd\n")); ok1(strstr(output, "--eee <filename> ")); ok1(strstr(output, " (default: eee)\n")); ok1(strstr(output, "long table options:\n")); ok1(strstr(output, "--ggg|-g ")); ok1(strstr(output, " Description of ggg\n")); ok1(strstr(output, "-h|--hhh <arg>")); ok1(strstr(output, " Description of hhh\n")); ok1(strstr(output, "--kkk|-k")); ok1(strstr(output, "magic kkk option")); /* This entry is hidden. */ ok1(!strstr(output, "--mmm|-m")); free(output); /* NULL should use string from registered options. */ output = opt_usage("my name", NULL); diag("%s", output); ok1(strstr(output, "Usage: my name")); ok1(strstr(output, "--jjj|-j|--lll|-l <arg>")); ok1(strstr(output, "<MyArgs>...")); ok1(strstr(output, "-a ")); ok1(strstr(output, " Description of a\n")); ok1(strstr(output, "-b <arg>")); ok1(strstr(output, " Description of b (default: b)\n")); ok1(strstr(output, "--ddd ")); ok1(strstr(output, " Description of ddd\n")); ok1(strstr(output, "--eee <filename> ")); ok1(strstr(output, " (default: eee)\n")); ok1(strstr(output, "long table options:\n")); ok1(strstr(output, "--ggg|-g ")); ok1(strstr(output, " Description of ggg\n")); ok1(strstr(output, "-h|--hhh <arg>")); ok1(strstr(output, " Description of hhh\n")); ok1(strstr(output, "--kkk|-k")); ok1(strstr(output, "magic kkk option")); ok1(strstr(output, "--longname")); ok1(strstr(output, "a really long option default")); ok1(strstr(output, "(default: \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"...)")); ok1(strstr(output, "--shortname")); ok1(strstr(output, "a short option default")); ok1(strstr(output, "(default: \"shortname\")")); /* This entry is hidden. */ ok1(!strstr(output, "--mmm|-m")); free(output); reset_options(); /* Empty table test. */ output = opt_usage("nothing", NULL); ok1(strstr(output, "Usage: nothing \n")); free(output); /* No short args. */ opt_register_noarg("--aaa", test_noarg, NULL, "AAAAll"); output = opt_usage("onearg", NULL); ok1(strstr(output, "Usage: onearg \n")); ok1(strstr(output, "--aaa")); ok1(strstr(output, "AAAAll")); free(output); free(shortname); free(longname); return exit_status(); }
/* Test that single onion poisoning works. */ static void test_single_onion_poisoning(void *arg) { or_options_t opt; mock_options = &opt; reset_options(mock_options, &mock_get_options_calls); MOCK(get_options, mock_get_options); int ret = -1; mock_options->DataDirectory = tor_strdup(get_fname("test_data_dir")); rend_service_t *service_1 = tor_malloc_zero(sizeof(rend_service_t)); char *dir1 = tor_strdup(get_fname("test_hs_dir1")); rend_service_t *service_2 = tor_malloc_zero(sizeof(rend_service_t)); char *dir2 = tor_strdup(get_fname("test_hs_dir2")); smartlist_t *services = smartlist_new(); (void) arg; /* No services, no problem! */ mock_options->HiddenServiceSingleHopMode = 0; mock_options->HiddenServiceNonAnonymousMode = 0; ret = rend_service_list_verify_single_onion_poison(services, mock_options); tt_assert(ret == 0); /* Either way, no problem. */ mock_options->HiddenServiceSingleHopMode = 1; mock_options->HiddenServiceNonAnonymousMode = 1; ret = rend_service_list_verify_single_onion_poison(services, mock_options); tt_assert(ret == 0); /* Create directories for both services */ #ifdef _WIN32 ret = mkdir(mock_options->DataDirectory); tt_assert(ret == 0); ret = mkdir(dir1); tt_assert(ret == 0); ret = mkdir(dir2); #else ret = mkdir(mock_options->DataDirectory, 0700); tt_assert(ret == 0); ret = mkdir(dir1, 0700); tt_assert(ret == 0); ret = mkdir(dir2, 0700); #endif tt_assert(ret == 0); service_1->directory = dir1; service_2->directory = dir2; dir1 = dir2 = NULL; smartlist_add(services, service_1); /* But don't add the second service yet. */ /* Service directories, but no previous keys, no problem! */ mock_options->HiddenServiceSingleHopMode = 0; mock_options->HiddenServiceNonAnonymousMode = 0; ret = rend_service_list_verify_single_onion_poison(services, mock_options); tt_assert(ret == 0); /* Either way, no problem. */ mock_options->HiddenServiceSingleHopMode = 1; mock_options->HiddenServiceNonAnonymousMode = 1; ret = rend_service_list_verify_single_onion_poison(services, mock_options); tt_assert(ret == 0); /* Poison! Poison! Poison! * This can only be done in HiddenServiceSingleHopMode. */ mock_options->HiddenServiceSingleHopMode = 1; mock_options->HiddenServiceNonAnonymousMode = 1; ret = rend_service_poison_new_single_onion_dirs(services); tt_assert(ret == 0); /* Poisoning twice is a no-op. */ ret = rend_service_poison_new_single_onion_dirs(services); tt_assert(ret == 0); /* Poisoned service directories, but no previous keys, no problem! */ mock_options->HiddenServiceSingleHopMode = 0; mock_options->HiddenServiceNonAnonymousMode = 0; ret = rend_service_list_verify_single_onion_poison(services, mock_options); tt_assert(ret == 0); /* Either way, no problem. */ mock_options->HiddenServiceSingleHopMode = 1; mock_options->HiddenServiceNonAnonymousMode = 1; ret = rend_service_list_verify_single_onion_poison(services, mock_options); tt_assert(ret == 0); /* Now add some keys, and we'll have a problem. */ ret = rend_service_load_all_keys(services); tt_assert(ret == 0); /* Poisoned service directories with previous keys are not allowed. */ mock_options->HiddenServiceSingleHopMode = 0; mock_options->HiddenServiceNonAnonymousMode = 0; ret = rend_service_list_verify_single_onion_poison(services, mock_options); tt_assert(ret < 0); /* But they are allowed if we're in non-anonymous mode. */ mock_options->HiddenServiceSingleHopMode = 1; mock_options->HiddenServiceNonAnonymousMode = 1; ret = rend_service_list_verify_single_onion_poison(services, mock_options); tt_assert(ret == 0); /* Re-poisoning directories with existing keys is a no-op, because * directories with existing keys are ignored. */ mock_options->HiddenServiceSingleHopMode = 1; mock_options->HiddenServiceNonAnonymousMode = 1; ret = rend_service_poison_new_single_onion_dirs(services); tt_assert(ret == 0); /* And it keeps the poison. */ ret = rend_service_list_verify_single_onion_poison(services, mock_options); tt_assert(ret == 0); /* Now add the second service: it has no key and no poison file */ smartlist_add(services, service_2); /* A new service, and an existing poisoned service. Not ok. */ mock_options->HiddenServiceSingleHopMode = 0; mock_options->HiddenServiceNonAnonymousMode = 0; ret = rend_service_list_verify_single_onion_poison(services, mock_options); tt_assert(ret < 0); /* But ok to add in non-anonymous mode. */ mock_options->HiddenServiceSingleHopMode = 1; mock_options->HiddenServiceNonAnonymousMode = 1; ret = rend_service_list_verify_single_onion_poison(services, mock_options); tt_assert(ret == 0); /* Now remove the poisoning from the first service, and we have the opposite * problem. */ char *poison_path = rend_service_sos_poison_path(service_1); ret = unlink(poison_path); tor_free(poison_path); tt_assert(ret == 0); /* Unpoisoned service directories with previous keys are ok, as are empty * directories. */ mock_options->HiddenServiceSingleHopMode = 0; mock_options->HiddenServiceNonAnonymousMode = 0; ret = rend_service_list_verify_single_onion_poison(services, mock_options); tt_assert(ret == 0); /* But the existing unpoisoned key is not ok in non-anonymous mode, even if * there is an empty service. */ mock_options->HiddenServiceSingleHopMode = 1; mock_options->HiddenServiceNonAnonymousMode = 1; ret = rend_service_list_verify_single_onion_poison(services, mock_options); tt_assert(ret < 0); /* Poisoning directories with existing keys is a no-op, because directories * with existing keys are ignored. But the new directory should poison. */ mock_options->HiddenServiceSingleHopMode = 1; mock_options->HiddenServiceNonAnonymousMode = 1; ret = rend_service_poison_new_single_onion_dirs(services); tt_assert(ret == 0); /* And the old directory remains unpoisoned. */ ret = rend_service_list_verify_single_onion_poison(services, mock_options); tt_assert(ret < 0); /* And the new directory should be ignored, because it has no key. */ mock_options->HiddenServiceSingleHopMode = 0; mock_options->HiddenServiceNonAnonymousMode = 0; ret = rend_service_list_verify_single_onion_poison(services, mock_options); tt_assert(ret == 0); /* Re-poisoning directories without existing keys is a no-op. */ mock_options->HiddenServiceSingleHopMode = 1; mock_options->HiddenServiceNonAnonymousMode = 1; ret = rend_service_poison_new_single_onion_dirs(services); tt_assert(ret == 0); /* And the old directory remains unpoisoned. */ ret = rend_service_list_verify_single_onion_poison(services, mock_options); tt_assert(ret < 0); done: /* TODO: should we delete the directories here? */ rend_service_free(service_1); rend_service_free(service_2); smartlist_free(services); UNMOCK(get_options); tor_free(mock_options->DataDirectory); tor_free(dir1); tor_free(dir2); }
static SANE_Status dev_inquiry (struct device *dev) { SANE_Byte *ptr; SANE_Char *optr, *xptr; if (!dev_cmd (dev, CMD_INQUIRY)) return SANE_STATUS_IO_ERROR; ptr = dev->res; if (ptr[3] != MSG_PRODUCT_INFO) { DBG (1, "%s: illegal INQUIRY response %02x\n", __FUNCTION__, ptr[3]); return SANE_STATUS_IO_ERROR; } /* parse reported manufacturer/product names */ dev->sane.vendor = optr = (SANE_Char *) malloc (33); for (ptr += 4; ptr < &dev->res[0x24] && *ptr && *ptr != ' ';) *optr++ = *ptr++; *optr++ = 0; for (; ptr < &dev->res[0x24] && (!*ptr || *ptr == ' '); ptr++) /* skip spaces */; dev->sane.model = optr = (SANE_Char *) malloc (33); xptr = optr; /* is last non space character + 1 */ for (; ptr < &dev->res[0x24] && *ptr;) { if (*ptr != ' ') xptr = optr + 1; *optr++ = *ptr++; } *optr++ = 0; *xptr = 0; DBG (1, "%s: found %s/%s\n", __FUNCTION__, dev->sane.vendor, dev->sane.model); dev->sane.type = strdup ("multi-function peripheral"); dev->resolutions = dev->res[0x37] << 16 | dev->res[0x24] << 8 | dev->res[0x25]; dev->compositions = dev->res[0x27]; dev->max_win_width = dev->res[0x28] << 24 | dev->res[0x29] << 16 | dev->res[0x2a] << 8 | dev->res[0x2b]; dev->max_win_len = dev->res[0x2c] << 24 | dev->res[0x2d] << 16 | dev->res[0x2e] << 8 | dev->res[0x2f]; dev->max_len_adf = dev->res[0x38] << 24 | dev->res[0x39] << 16 | dev->res[0x3a] << 8 | dev->res[0x3b]; dev->max_len_fb = dev->res[0x3c] << 24 | dev->res[0x3d] << 16 | dev->res[0x3e] << 8 | dev->res[0x3f]; dev->line_order = dev->res[0x31]; dev->doc_loaded = (dev->res[0x35] == 0x02) && (dev->res[0x26] & 0x03); init_options(dev); reset_options(dev); fix_window(dev); set_parameters(dev); resolv_inq_dpi(dev); return SANE_STATUS_GOOD; }
int main(int argc, char *argv[]) { const char *myname = argv[0]; plan_tests(215); /* Simple short arg.*/ opt_register_noarg("-a", test_noarg, NULL, "All"); ok1(parse_args(&argc, &argv, "-a", NULL)); ok1(argc == 1); ok1(argv[0] == myname); ok1(argv[1] == NULL); ok1(test_cb_called == 1); /* Simple long arg. */ opt_register_noarg("--aaa", test_noarg, NULL, "AAAAll"); ok1(parse_args(&argc, &argv, "--aaa", NULL)); ok1(argc == 1); ok1(argv[0] == myname); ok1(argv[1] == NULL); ok1(test_cb_called == 2); /* Both long and short args. */ opt_register_noarg("--aaa|-a", test_noarg, NULL, "AAAAAAll"); ok1(parse_args(&argc, &argv, "--aaa", "-a", NULL)); ok1(argc == 1); ok1(argv[0] == myname); ok1(argv[1] == NULL); ok1(test_cb_called == 4); /* Extra arguments preserved. */ ok1(parse_args(&argc, &argv, "--aaa", "-a", "extra", "args", NULL)); ok1(argc == 3); ok1(argv[0] == myname); ok1(strcmp(argv[1], "extra") == 0); ok1(strcmp(argv[2], "args") == 0); ok1(test_cb_called == 6); /* Malformed versions. */ ok1(!parse_args(&argc, &argv, "--aaa=arg", NULL)); ok1(strstr(err_output, ": --aaa: doesn't allow an argument")); ok1(!parse_args(&argc, &argv, "--aa", NULL)); ok1(strstr(err_output, ": --aa: unrecognized option")); ok1(!parse_args(&argc, &argv, "--aaargh", NULL)); ok1(strstr(err_output, ": --aaargh: unrecognized option")); /* Argument variants. */ reset_options(); test_cb_called = 0; opt_register_arg("-a|--aaa", test_arg, NULL, "aaa", "AAAAAAll"); ok1(parse_args(&argc, &argv, "--aaa", "aaa", NULL)); ok1(argc == 1); ok1(argv[0] == myname); ok1(test_cb_called == 1); ok1(parse_args(&argc, &argv, "--aaa=aaa", NULL)); ok1(argc == 1); ok1(argv[0] == myname); ok1(test_cb_called == 2); ok1(parse_args(&argc, &argv, "-a", "aaa", NULL)); ok1(argc == 1); ok1(argv[0] == myname); ok1(test_cb_called == 3); /* Malformed versions. */ ok1(!parse_args(&argc, &argv, "-a", NULL)); ok1(strstr(err_output, ": -a: requires an argument")); ok1(!parse_args(&argc, &argv, "--aaa", NULL)); ok1(strstr(err_output, ": --aaa: requires an argument")); ok1(!parse_args(&argc, &argv, "--aa", NULL)); ok1(strstr(err_output, ": --aa: unrecognized option")); ok1(!parse_args(&argc, &argv, "--aaargh", NULL)); ok1(strstr(err_output, ": --aaargh: unrecognized option")); /* Now, tables. */ /* Short table: */ reset_options(); test_cb_called = 0; opt_register_table(short_table, NULL); ok1(parse_args(&argc, &argv, "-a", NULL)); ok1(argc == 1); ok1(argv[0] == myname); ok1(argv[1] == NULL); ok1(test_cb_called == 1); /* This one needs an arg. */ ok1(parse_args(&argc, &argv, "-b", NULL) == false); ok1(test_cb_called == 1); ok1(parse_args(&argc, &argv, "-b", "b", NULL)); ok1(argc == 1); ok1(argv[0] == myname); ok1(argv[1] == NULL); ok1(test_cb_called == 2); /* Long table: */ reset_options(); test_cb_called = 0; opt_register_table(long_table, NULL); ok1(parse_args(&argc, &argv, "--ddd", NULL)); ok1(argc == 1); ok1(argv[0] == myname); ok1(argv[1] == NULL); ok1(test_cb_called == 1); /* This one needs an arg. */ ok1(parse_args(&argc, &argv, "--eee", NULL) == false); ok1(test_cb_called == 1); ok1(parse_args(&argc, &argv, "--eee", "eee", NULL)); ok1(argc == 1); ok1(argv[0] == myname); ok1(argv[1] == NULL); ok1(test_cb_called == 2); /* Short and long, both. */ reset_options(); test_cb_called = 0; opt_register_table(long_and_short_table, NULL); ok1(parse_args(&argc, &argv, "-g", NULL)); ok1(argc == 1); ok1(argv[0] == myname); ok1(argv[1] == NULL); ok1(test_cb_called == 1); ok1(parse_args(&argc, &argv, "--ggg", NULL)); ok1(argc == 1); ok1(argv[0] == myname); ok1(argv[1] == NULL); ok1(test_cb_called == 2); /* This one needs an arg. */ ok1(parse_args(&argc, &argv, "-h", NULL) == false); ok1(test_cb_called == 2); ok1(parse_args(&argc, &argv, "-h", "hhh", NULL)); ok1(argc == 1); ok1(argv[0] == myname); ok1(argv[1] == NULL); ok1(test_cb_called == 3); ok1(parse_args(&argc, &argv, "--hhh", NULL) == false); ok1(test_cb_called == 3); ok1(parse_args(&argc, &argv, "--hhh", "hhh", NULL)); ok1(argc == 1); ok1(argv[0] == myname); ok1(argv[1] == NULL); ok1(test_cb_called == 4); /* Those will all work as tables. */ test_cb_called = 0; reset_options(); opt_register_table(subtables, NULL); ok1(parse_args(&argc, &argv, "-a", NULL)); ok1(argc == 1); ok1(argv[0] == myname); ok1(argv[1] == NULL); ok1(test_cb_called == 1); /* This one needs an arg. */ ok1(parse_args(&argc, &argv, "-b", NULL) == false); ok1(test_cb_called == 1); ok1(parse_args(&argc, &argv, "-b", "b", NULL)); ok1(argc == 1); ok1(argv[0] == myname); ok1(argv[1] == NULL); ok1(test_cb_called == 2); ok1(parse_args(&argc, &argv, "--ddd", NULL)); ok1(argc == 1); ok1(argv[0] == myname); ok1(argv[1] == NULL); ok1(test_cb_called == 3); /* This one needs an arg. */ ok1(parse_args(&argc, &argv, "--eee", NULL) == false); ok1(test_cb_called == 3); ok1(parse_args(&argc, &argv, "--eee", "eee", NULL)); ok1(argc == 1); ok1(argv[0] == myname); ok1(argv[1] == NULL); ok1(test_cb_called == 4); /* Short and long, both. */ ok1(parse_args(&argc, &argv, "-g", NULL)); ok1(argc == 1); ok1(argv[0] == myname); ok1(argv[1] == NULL); ok1(test_cb_called == 5); ok1(parse_args(&argc, &argv, "--ggg", NULL)); ok1(argc == 1); ok1(argv[0] == myname); ok1(argv[1] == NULL); ok1(test_cb_called == 6); /* This one needs an arg. */ ok1(parse_args(&argc, &argv, "-h", NULL) == false); ok1(test_cb_called == 6); ok1(parse_args(&argc, &argv, "-h", "hhh", NULL)); ok1(argc == 1); ok1(argv[0] == myname); ok1(argv[1] == NULL); ok1(test_cb_called == 7); ok1(parse_args(&argc, &argv, "--hhh", NULL) == false); ok1(test_cb_called == 7); ok1(parse_args(&argc, &argv, "--hhh", "hhh", NULL)); ok1(argc == 1); ok1(argv[0] == myname); ok1(argv[1] == NULL); ok1(test_cb_called == 8); /* Now the tricky one: -? must not be confused with an unknown option */ test_cb_called = 0; reset_options(); /* glibc's getopt does not handle ? with arguments. */ opt_register_noarg("-?", test_noarg, NULL, "Help"); ok1(parse_args(&argc, &argv, "-?", NULL)); ok1(test_cb_called == 1); ok1(parse_args(&argc, &argv, "-a", NULL) == false); ok1(test_cb_called == 1); ok1(strstr(err_output, ": -a: unrecognized option")); ok1(parse_args(&argc, &argv, "--aaaa", NULL) == false); ok1(test_cb_called == 1); ok1(strstr(err_output, ": --aaaa: unrecognized option")); test_cb_called = 0; reset_options(); /* Corner cases involving short arg parsing weirdness. */ opt_register_noarg("-a|--aaa", test_noarg, NULL, "a"); opt_register_arg("-b|--bbb", test_arg, NULL, "bbb", "b"); opt_register_arg("-c|--ccc", test_arg, NULL, "aaa", "c"); /* -aa == -a -a */ ok1(parse_args(&argc, &argv, "-aa", NULL)); ok1(test_cb_called == 2); ok1(parse_args(&argc, &argv, "-aab", NULL) == false); ok1(test_cb_called == 4); ok1(strstr(err_output, ": -b: requires an argument")); ok1(parse_args(&argc, &argv, "-bbbb", NULL)); ok1(test_cb_called == 5); ok1(parse_args(&argc, &argv, "-aabbbb", NULL)); ok1(test_cb_called == 8); ok1(parse_args(&argc, &argv, "-aabbbb", "-b", "bbb", NULL)); ok1(test_cb_called == 12); ok1(parse_args(&argc, &argv, "-aabbbb", "--bbb", "bbb", NULL)); ok1(test_cb_called == 16); ok1(parse_args(&argc, &argv, "-aabbbb", "--bbb=bbb", NULL)); ok1(test_cb_called == 20); ok1(parse_args(&argc, &argv, "-aacaaa", NULL)); ok1(test_cb_called == 23); ok1(parse_args(&argc, &argv, "-aacaaa", "-a", NULL)); ok1(test_cb_called == 27); ok1(parse_args(&argc, &argv, "-aacaaa", "--bbb", "bbb", "-aacaaa", NULL)); ok1(test_cb_called == 34); test_cb_called = 0; reset_options(); /* -- and POSIXLY_CORRECT */ opt_register_noarg("-a|--aaa", test_noarg, NULL, "a"); ok1(parse_args(&argc, &argv, "-a", "--", "-a", NULL)); ok1(test_cb_called == 1); ok1(argc == 2); ok1(strcmp(argv[1], "-a") == 0); ok1(!argv[2]); unsetenv("POSIXLY_CORRECT"); ok1(parse_args(&argc, &argv, "-a", "somearg", "-a", "--", "-a", NULL)); ok1(test_cb_called == 3); ok1(argc == 3); ok1(strcmp(argv[1], "somearg") == 0); ok1(strcmp(argv[2], "-a") == 0); ok1(!argv[3]); setenv("POSIXLY_CORRECT", "1", 1); ok1(parse_args(&argc, &argv, "-a", "somearg", "-a", "--", "-a", NULL)); ok1(test_cb_called == 4); ok1(argc == 5); ok1(strcmp(argv[1], "somearg") == 0); ok1(strcmp(argv[2], "-a") == 0); ok1(strcmp(argv[3], "--") == 0); ok1(strcmp(argv[4], "-a") == 0); ok1(!argv[5]); /* parse_args allocates argv */ free(argv); return exit_status(); }