OSCommandLine::OSCommandLine():
	osinstance(NULL),
	osoption(NULL)
{
#ifdef DEBUG_COMMANDLINE
	std::cout << "Inside command line constructor" << std::endl;
#endif
	reset_options();
}
Пример #2
0
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");
}
Пример #3
0
/* 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);
}
Пример #4
0
/* 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();
}
Пример #5
0
/* 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();
}
Пример #6
0
/* 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);
}
Пример #7
0
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;
}
Пример #8
0
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();
}