Beispiel #1
0
static void
vrrp_handler(vector_t *strvec)
{
	list l;
	element e;
	vrrp_t *vrrp;
	char *iname;

	if (vector_count(strvec) != 2) {
		log_message(LOG_INFO, "vrrp_instance must have a name");
		skip_block();
		return;
	}

	iname = vector_slot(strvec,1);

	/* Make sure the vrrp instance doesn't already exist */
	if (!LIST_ISEMPTY(vrrp_data->vrrp)) {
		l = vrrp_data->vrrp;
		for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
			vrrp = ELEMENT_DATA(e);
			if (!strcmp(iname,vrrp->iname)) {
				log_message(LOG_INFO, "vrrp instance %s already defined", iname );
				skip_block();
				return;
			}
		}
	}

	alloc_vrrp(iname);
}
Beispiel #2
0
static void
bfd_nbrip_handler(vector_t *strvec)
{
	bfd_t *bfd;
	struct sockaddr_storage nbr_addr;

	assert(strvec);
	assert(bfd_data);

	bfd = LIST_TAIL_DATA(bfd_data->bfd);
	assert(bfd);

	if (!strcmp(vector_slot(strvec, 1), "neighbour_ip"))
		neighbor_str = "neighbour";

	if (inet_stosockaddr(strvec_slot(strvec, 1), BFD_CONTROL_PORT, &nbr_addr)) {
		report_config_error(CONFIG_GENERAL_ERROR,
			    "Configuration error: BFD instance %s has"
			    " malformed %s address %s, ignoring instance",
			    bfd->iname, neighbor_str, FMT_STR_VSLOT(strvec, 1));
		list_del(bfd_data->bfd, bfd);
		skip_block(false);
		return;
	} else if (find_bfd_by_addr(&nbr_addr)) {
		report_config_error(CONFIG_GENERAL_ERROR,
			    "Configuration error: BFD instance %s has"
			    " duplicate %s address %s, ignoring instance",
			    bfd->iname, neighbor_str, FMT_STR_VSLOT(strvec, 1));
		list_del(bfd_data->bfd, bfd);
		skip_block(false);
		return;
	} else
		bfd->nbr_addr = nbr_addr;
}
Beispiel #3
0
/* VRRP handlers */
static void
vrrp_sync_group_handler(vector_t *strvec)
{
	list l;
	element e;
	vrrp_sgroup_t *sg;
	char* gname;

	if (vector_count(strvec) != 2) {
		log_message(LOG_INFO, "vrrp_sync_group must have a name - skipping");
		skip_block();
		return;
	}

	gname = vector_slot(strvec, 1);

	/* check group doesn't already exist */
	if (!LIST_ISEMPTY(vrrp_data->vrrp_sync_group)) {
		l = vrrp_data->vrrp_sync_group;
		for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
			sg = ELEMENT_DATA(e);
			if (!strcmp(gname,sg->gname)) {
				log_message(LOG_INFO, "vrrp sync group %s already defined", gname);
				skip_block();
				return;
			}
		}
	}

	alloc_vrrp_sync_group(gname);
}
Beispiel #4
0
int
main(void)
{
    struct script_config config;
    struct kerberos_config *krbconf;

    /* Skip the test if FAST is not available. */
#ifndef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_FAST_CCACHE_NAME
    skip_all("FAST support not available");
#endif

    /*
     * To test FAST with an existing ticket cache, we also need a keytab, but
     * we can test anonymous FAST without that.  So only say that we require a
     * password.
     */
    krbconf = kerberos_setup(TAP_KRB_NEEDS_PASSWORD);
    memset(&config, 0, sizeof(config));
    config.user = krbconf->userprinc;
    config.authtok = krbconf->password;

    /*
     * Generate a testing krb5.conf file with a nonexistent default realm so
     * that we can be sure that our principals will stay fully-qualified in
     * the logs.
     */
    kerberos_generate_conf("bogus.example.com");

    plan_lazy();

    /* If we have a keytab and ticket cache available, test fast_ccache. */
    if (krbconf->keytab == NULL)
        skip_block(4, "Kerberos keytab required to test fast_ccache");
    else {
        config.extra[0] = krbconf->cache;
        run_script("data/scripts/fast/ccache", &config);
        run_script("data/scripts/fast/ccache-debug", &config);
        run_script("data/scripts/fast/no-ccache", &config);
        run_script("data/scripts/fast/no-ccache-debug", &config);
    }

    /*
     * Test anonymous FAST.  This will require some pre-testing later.  For
     * this, we need to use our real local realm.
     */
    kerberos_generate_conf(krbconf->realm);
    config.user = krbconf->username;
    config.extra[0] = krbconf->userprinc;
    if (anon_fast_works()) {
        run_script("data/scripts/fast/anonymous", &config);
        run_script("data/scripts/fast/anonymous-debug", &config);
    } else {
        skip_block(2, "Anonymous authentication required to test anon_fast");
    }

    return 0;
}
const char *JavaScript(const char *txt, PopupList &lstJsFunctions, PopupList &lstJsClasses, bool sorted)
{
	txt = skip_nc(txt, '>');
	
	while (*txt)
	{
		switch (*txt)
		{
			case '/':
				if (*(txt + 1) == '/')
					txt = skip(txt, '\n') - 1;
				break;

			case '"':
			case '\'':
				skip_string(txt);
				break;

			case '(':
				txt = skip_block(txt + 1, '(', ')');
				break;

			case '{':
				txt = skip_block(txt + 1, '{', '}');
				break;

			case '<':
				if (strncasecmp(txt, "</script", 8) == 0)
					return txt + 9;
				break;

			default:
				if (strncasecmp(txt, "function", 8) == 0)
				{
					txt += 8;
					while (isspace(*txt)) txt++;
					
					const char *beg = txt;
					while ((isalnum(*txt) || *txt == '.' || *txt == '_'))
					{
						txt++;
					}

					BString label, function(beg, txt-beg);
					if (sorted)
						label << SORT_PREFIX_JS;
					label << function;

					lstJsFunctions.insert(lstJsFunctions.end(), PopupMenu(label, function, beg));
				}
				break;
		}
		txt++;
	}
	
	return txt;
} /* JavaScript */
Beispiel #6
0
	static const char* skip_value(const char* json)
	{
		CE_ASSERT_NOT_NULL(json);

		switch (*json)
		{
			case '"': json = skip_string(json); break;
			case '[': json = skip_block(json, '[', ']'); break;
			case '{': json = skip_block(json, '{', '}'); break;
			default: for (; *json != '\0' && *json != ',' && *json != '\n' && *json != ' ' && *json != '}' && *json != ']'; ++json) ; break;
		}

		return json;
	}
Beispiel #7
0
/**
 * Try to get the 'description' block from a savefile.  Fail gracefully.
 */
const char *savefile_get_description(const char *path) {
	struct blockheader b;

	ang_file *f = file_open(path, MODE_READ, FTYPE_TEXT);
	if (!f) return NULL;

	/* Blank the description */
	savefile_desc[0] = 0;

	if (!check_header(f)) {
		my_strcpy(savefile_desc, "Invalid savefile", sizeof savefile_desc);
	} else {
		while (!next_blockheader(f, &b)) {
			if (!streq(b.name, "description")) {
				skip_block(f, &b);
				continue;
			}
			load_block(f, &b, get_desc);
			break;
		}
	}

	file_close(f);
	return savefile_desc;
}
void php_function(const char *&txt, PopupList &pul, BString &className, bool sorted)
{
	BString label, function, params;
	txt = skip_whitespace(txt+8);

	const char *beg = txt;
	while (isident(*++txt)) ;
	function.SetTo(beg, txt-beg);

	txt = skip_whitespace(txt);
	if (*txt == '(') {
		const char* ptr = txt;
		txt = skip_block(txt+1, '(', ')');
		params.SetTo(ptr+1, txt-ptr-2);
		params.Prepend("  (");
		params.Append(")");
	}
	if (sorted)
	{
		label << SORT_PREFIX_PHP;
		if (className != "")
		{
			label << className << "::";
		}
	}
	else
	{
		if (className != "")
		{
			label << "• ";
		}
	}
	label << function << params;
	pul.insert(pul.end(), PopupMenu(label, function, beg));
} /* php_function */
Beispiel #9
0
int
main(void)
{
    pam_handle_t *pamh;
    struct pam_args *args;
    struct pam_conv conv = { NULL, NULL };
    char *expected;
    struct output *seen;
#ifdef HAVE_KRB5
    krb5_error_code code;
    krb5_principal princ;
#endif

    plan(27);

    if (pam_start("test", NULL, &conv, &pamh) != PAM_SUCCESS)
        sysbail("Fake PAM initialization failed");
    args = putil_args_new(pamh, 0);
    if (args == NULL)
        bail("cannot create PAM argument struct");
    TEST(putil_crit,  LOG_CRIT,  "putil_crit");
    TEST(putil_err,   LOG_ERR,   "putil_err");
    putil_debug(args, "%s", "foo");
    ok(pam_output() == NULL, "putil_debug without debug on");
    args->debug = true;
    TEST(putil_debug, LOG_DEBUG, "putil_debug");
    args->debug = false;

    TEST_PAM(putil_crit_pam,  PAM_SYSTEM_ERR, LOG_CRIT,  "putil_crit_pam S");
    TEST_PAM(putil_crit_pam,  PAM_BUF_ERR,    LOG_CRIT,  "putil_crit_pam B");
    TEST_PAM(putil_crit_pam,  PAM_SUCCESS,    LOG_CRIT,  "putil_crit_pam ok");
    TEST_PAM(putil_err_pam,   PAM_SYSTEM_ERR, LOG_ERR,   "putil_err_pam");
    putil_debug_pam(args, PAM_SYSTEM_ERR, "%s", "bar");
    ok(pam_output() == NULL, "putil_debug_pam without debug on");
    args->debug = true;
    TEST_PAM(putil_debug_pam, PAM_SYSTEM_ERR, LOG_DEBUG, "putil_debug_pam");
    TEST_PAM(putil_debug_pam, PAM_SUCCESS,    LOG_DEBUG, "putil_debug_pam ok");
    args->debug = false;

#ifdef HAVE_KRB5
    TEST_KRB5(putil_crit_krb5,  LOG_CRIT,  "putil_crit_krb5");
    TEST_KRB5(putil_err_krb5,   LOG_ERR,   "putil_err_krb5");
    code = krb5_parse_name(args->ctx, "foo@[email protected]", &princ);
    putil_debug_krb5(args, code, "%s", "krb");
    ok(pam_output() == NULL, "putil_debug_krb5 without debug on");
    args->debug = true;
    TEST_KRB5(putil_debug_krb5, LOG_DEBUG, "putil_debug_krb5");
    args->debug = false;
#else
    skip_block(4, "not built with Kerberos support");
#endif

    putil_args_free(args);
    pam_end(pamh, 0);

    return 0;
}
Beispiel #10
0
Datei: edns.c Projekt: idtek/knot
int main(int argc, char *argv[])
{
	plan(TEST_COUNT);
	int done = 0;

	knot_rrset_t opt_rr;
	int ret = knot_edns_init(&opt_rr, E_MAX_PLD, E_RCODE, E_VERSION, NULL);

	ok(ret == KNOT_EOK, "OPT RR: init");
	done++;

	/* Check initialized values (no NSID yet). */
	bool success = check_header(&opt_rr, E_MAX_PLD, E_VERSION, 0, E_RCODE,
	                            "OPT RR: check header", &done);
	if (!success) {
		skip_block(remaining(done), "OPT RR not initialized properly");
		goto exit;
	}

	/* Setters */
	success = test_setters(&opt_rr, &done);

	if (!success) {
		skip_block(remaining(done), "OPT RR: setters error");
		goto exit;
	}

	/* Getters
	   Note: NULL parameters are not supported, so no test for that. */
	success = test_getters(&opt_rr, &done);

	if (!success) {
		skip_block(remaining(done), "OPT RR: getters error");
		goto exit;
	}

	/* EDNS client subnet */
	test_client_subnet();
exit:
	knot_rrset_clear(&opt_rr, NULL);

	return 0;
}
Beispiel #11
0
static void
vrrp_group_handler(vector_t *strvec)
{
	vrrp_sgroup_t *vgroup = LIST_TAIL_DATA(vrrp_data->vrrp_sync_group);

	if (vgroup->iname) {
		log_message(LOG_INFO, "Group list already specified for sync group %s", vgroup->gname);
		skip_block();
		return;
	}

	vgroup->iname = read_value_block(strvec);
}
Beispiel #12
0
/* Basic response check (4 TAP tests). */
static void answer_sanity_check(const uint8_t *query,
                                const uint8_t *answer, uint16_t answer_len,
                                uint8_t expected_rcode, const char *name)
{
	ok(answer_len >= KNOT_WIRE_HEADER_SIZE, "ns: len(%s answer) >= DNS header", name);
	if (answer_len >= KNOT_WIRE_HEADER_SIZE) {
		ok(knot_wire_get_qr(answer), "ns: %s answer has QR=1", name);
		is_int(expected_rcode, knot_wire_get_rcode(answer), "ns: %s answer RCODE=%d", name, expected_rcode);
		is_int(knot_wire_get_id(query), knot_wire_get_id(answer), "ns: %s MSGID match", name);
	} else {
		skip_block(3, "ns: can't check DNS header");
	}

}
Beispiel #13
0
void CJSourceParser::SkipFunction( char*& cur )
{
    while ( *cur != '(' && cur < _gSrcEnd )
    {
        if (*cur == 10 ) ++_gLineNo;
        ++cur;
    }

    skip_next_token_back( cur ); // go back and skip function identifier
    skip_token_back( cur );      // go back and skip return type

    skip_block( cur );           // now, go ahead and skip whole declaration

    SkipFunctionBody( cur );

}
Beispiel #14
0
int
main(void)
{
    pam_handle_t *pamh;
    struct pam_conv conv = { NULL, NULL };
    struct pam_args *args;

    plan(12);

    if (pam_start("test", NULL, &conv, &pamh) != PAM_SUCCESS)
        sysbail("Fake PAM initialization failed");
    args = putil_args_new(pamh, 0);
    ok(args != NULL, "New args struct is not NULL");
    if (args == NULL)
        ok_block(7, 0, "...args struct is NULL");
    else {
        ok(args->pamh == pamh, "...and pamh is correct");
        ok(args->config == NULL, "...and config is NULL");
        ok(args->user == NULL, "...and user is NULL");
        is_int(args->debug, false, "...and debug is false");
        is_int(args->silent, false, "...and silent is false");
#ifdef HAVE_KRB5
        ok(args->ctx != NULL, "...and the Kerberos context is initialized");
        ok(args->realm == NULL, "...and realm is NULL");
#else
        skip_block(2, "Kerberos support not configured");
#endif
    }
    putil_args_free(args);
    ok(1, "Freeing the args struct works");

    args = putil_args_new(pamh, PAM_SILENT);
    ok(args != NULL, "New args struct with PAM_SILENT is not NULL");
    if (args == NULL)
        ok(0, "...args is NULL");
    else
        is_int(args->silent, true, "...and silent is true");
    putil_args_free(args);

    putil_args_free(NULL);
    ok(1, "Freeing a NULL args struct works");

    pam_end(pamh, 0);

    return 0;
}
const char *skip_block(const char *txt, char open, char close)
{
	while (*txt)
	{
		if (*txt == open)
			txt = skip_block(txt + 1, open, close);

		else if (*txt == close)
			return txt + 1;

		else if (*txt == '"' || *txt == '\'')
		{
			skip_string(txt);
			++txt;
		}
		else
			++txt;
	}
	return txt;
} /* block */
Beispiel #16
0
static void
bfd_handler(vector_t *strvec)
{
	char *name;

	global_data->have_bfd_config = true;

	/* If we are not the bfd process, we don't need any more information */
	if (!strvec)
		return;

	name = vector_slot(strvec, 1);

	if (!check_new_bfd(name)) {
		skip_block(true);
		return;
	}

	alloc_bfd(name);

	specified_event_processes = 0;
}
Beispiel #17
0
Datei: pkt.c Projekt: idtek/knot
int main(int argc, char *argv[])
{
	plan(25);

	/* Create memory pool context. */
	int ret = 0;
	knot_mm_t mm;
	mm_ctx_mempool(&mm, MM_DEFAULT_BLKSIZE);

	/* Create names and data. */
	knot_dname_t* dnames[NAMECOUNT] = {0};
	knot_rrset_t* rrsets[NAMECOUNT] = {0};
	for (unsigned i = 0; i < NAMECOUNT; ++i) {
		dnames[i] = knot_dname_from_str_alloc(g_names[i]);
	}

	uint8_t *edns_str = (uint8_t *)"ab";
	/* Create OPT RR. */
	knot_rrset_t opt_rr;
	ret = knot_edns_init(&opt_rr, 1024, 0, 0, &mm);
	if (ret != KNOT_EOK) {
		skip_block(25, "Failed to initialize OPT RR.");
		return 0;
	}
	/* Add NSID */
	ret = knot_edns_add_option(&opt_rr, KNOT_EDNS_OPTION_NSID,
	                           strlen((char *)edns_str), edns_str, &mm);
	if (ret != KNOT_EOK) {
		knot_rrset_clear(&opt_rr, &mm);
		skip_block(25, "Failed to add NSID to OPT RR.");
		return 0;
	}

	/*
	 * Packet writer tests.
	 */

	/* Create packet. */
	knot_pkt_t *out = knot_pkt_new(NULL, MM_DEFAULT_BLKSIZE, &mm);
	ok(out != NULL, "pkt: new");

	/* Mark as response (not part of the test). */
	knot_wire_set_qr(out->wire);

	/* Secure packet. */
	const char *tsig_secret = "abcd";
	knot_tsig_key_t tsig_key;
	tsig_key.algorithm = DNSSEC_TSIG_HMAC_MD5;
	tsig_key.name = dnames[0];
	tsig_key.secret.data = (uint8_t *)strdup(tsig_secret);
	tsig_key.secret.size = strlen(tsig_secret);
	ret = knot_pkt_reserve(out, knot_tsig_wire_maxsize(&tsig_key));
	ok(ret == KNOT_EOK, "pkt: set TSIG key");

	/* Write question. */
	ret = knot_pkt_put_question(out, dnames[0], KNOT_CLASS_IN, KNOT_RRTYPE_A);
	ok(ret == KNOT_EOK, "pkt: put question");

	/* Add OPT to packet (empty NSID). */
	ret = knot_pkt_reserve(out, knot_edns_wire_size(&opt_rr));
	ok(ret == KNOT_EOK, "pkt: reserve OPT RR");

	/* Begin ANSWER section. */
	ret = knot_pkt_begin(out, KNOT_ANSWER);
	ok(ret == KNOT_EOK, "pkt: begin ANSWER");

	/* Write ANSWER section. */
	rrsets[0] = knot_rrset_new(dnames[0], KNOT_RRTYPE_A, KNOT_CLASS_IN, NULL);
	knot_dname_free(&dnames[0], NULL);
	knot_rrset_add_rdata(rrsets[0], RDVAL(0), RDLEN(0), TTL, NULL);
	ret = knot_pkt_put(out, KNOT_COMPR_HINT_QNAME, rrsets[0], 0);
	ok(ret == KNOT_EOK, "pkt: write ANSWER");

	/* Begin AUTHORITY. */
	ret = knot_pkt_begin(out, KNOT_AUTHORITY);
	ok(ret == KNOT_EOK, "pkt: begin AUTHORITY");

	/* Write rest to AUTHORITY. */
	ret = KNOT_EOK;
	for (unsigned i = 1; i < NAMECOUNT; ++i) {
		rrsets[i] = knot_rrset_new(dnames[i], KNOT_RRTYPE_NS, KNOT_CLASS_IN, NULL);
		knot_dname_free(&dnames[i], NULL);
		knot_rrset_add_rdata(rrsets[i], RDVAL(i), RDLEN(i), TTL, NULL);
		ret |= knot_pkt_put(out, KNOT_COMPR_HINT_NONE, rrsets[i], 0);
	}
	ok(ret == KNOT_EOK, "pkt: write AUTHORITY(%u)", NAMECOUNT - 1);

	/* Begin ADDITIONALS */
	ret = knot_pkt_begin(out, KNOT_ADDITIONAL);
	ok(ret == KNOT_EOK, "pkt: begin ADDITIONALS");

	/* Encode OPT RR. */
	ret = knot_pkt_put(out, KNOT_COMPR_HINT_NONE, &opt_rr, 0);
	ok(ret == KNOT_EOK, "pkt: write OPT RR");

	/*
	 * Packet reader tests.
	 */

	/* Create new packet from query packet. */
	knot_pkt_t *in = knot_pkt_new(out->wire, out->size, &out->mm);
	ok(in != NULL, "pkt: create packet for parsing");

	/* Read packet header. */
	ret = knot_pkt_parse_question(in);
	ok(ret == KNOT_EOK, "pkt: read header");

	/* Read packet payload. */
	ret = knot_pkt_parse_payload(in, 0);
	ok(ret == KNOT_EOK, "pkt: read payload");

	/* Compare parsed packet to written packet. */
	packet_match(in, out);

	/*
	 * Copied packet tests.
	 */
	knot_pkt_t *copy = knot_pkt_new(NULL, in->max_size, &in->mm);
	ret = knot_pkt_copy(copy, in);
	ok(ret == KNOT_EOK, "pkt: create packet copy");

	/* Compare copied packet to original. */
	packet_match(in, copy);

	/* Free packets. */
	knot_pkt_free(&copy);
	knot_pkt_free(&out);
	knot_pkt_free(&in);
	ok(in == NULL && out == NULL && copy == NULL, "pkt: free");

	/* Free extra data. */
	for (unsigned i = 0; i < NAMECOUNT; ++i) {
		knot_rrset_free(&rrsets[i], NULL);
	}
	free(tsig_key.secret.data);
	mp_delete((struct mempool *)mm.ctx);

	return 0;
}
Beispiel #18
0
int
main(void)
{
    struct kerberos_config *config;
    const char *cache;
    struct remctl *r;
    struct remctl_output *output;
    int status;
    const char *command[] = { "test", "test", NULL };

    /* Set up Kerberos and remctld. */
    config = kerberos_setup(TAP_KRB_NEEDS_KEYTAB);
    remctld_start(config, "data/conf-simple", (char *) 0);

    plan(12);

    /* Get the current ticket cache and then change KRB5CCNAME. */
    cache = getenv("KRB5CCNAME");
    if (cache == NULL)
        bail("failed to set KRB5CCNAME");
    putenv((char *) "KRB5CCNAME=./nonexistent-file");

    /* Connecting without setting the ticket cache should fail. */
    r = remctl_new();
    ok(r != NULL, "remctl_new");
    ok(!remctl_open(r, "127.0.0.1", 14373, config->principal),
       "remctl_open to 127.0.0.1");

    /* Set the ticket cache and connect to 127.0.0.1 and run a command. */
    status = remctl_set_ccache(r, cache);
    if (!status) {
        is_string("setting credential cache not supported", remctl_error(r),
                  "remctl_set_ccache failed with correct error");
        skip_block(9, "credential cache setting not supported");
    } else {
        ok(remctl_set_ccache(r, cache), "remctl_set_ccache");
        ok(remctl_open(r, "127.0.0.1", 14373, config->principal),
           "remctl_open to 127.0.0.1");
        ok(remctl_command(r, command), "remctl_command");
        output = remctl_output(r);
        ok(output != NULL, "remctl_output #1");
        if (output == NULL)
            ok_block(3, 0, "remctl_output failed");
        else {
            is_int(REMCTL_OUT_OUTPUT, output->type, "output token");
            ok(memcmp("hello world\n", output->data,
                      strlen("hello world\n")) == 0,
               "correct output");
            is_int(strlen("hello world\n"), output->length, "correct length");
        }
        output = remctl_output(r);
        ok(output != NULL, "remctl_output #2");
        if (output == NULL)
            ok_block(2, 0, "remctl_output failed");
        else {
            is_int(REMCTL_OUT_STATUS, output->type, "status token");
            is_int(0, output->status, "status is correct");
        }
    }
    remctl_close(r);

    return 0;
}
const char *PhpScript(const char *txt, PopupList &lstPhpFunctions, PopupList &lstPhpClasses, bool sorted)
{
	std::map <int,int,int> headings;
	BString class_name;
	while (*txt)
	{
//printf("%c", *txt);
		switch (*txt)
		{
			case '/':
				// Comment: "//..."
				if (*(txt + 1) == '/')
					txt = skip(txt + 2, '\n') - 1;
				// Comment: "/*..."
				else if (*(txt + 1) == '*')
				{
					txt++;
					while ( *++txt &&
							!(*txt == '?' && *(txt + 1) == '>') &&
							!(*txt == '*' && *(txt + 1) == '/'))
						;
					txt++;
				}
				break;

			case '"':
			case '\'':
				skip_string(txt);
				break;

			case '}':
				//printf("\nCLASSEND FOUND\n");
				class_name = "";
				break;

			case '{':
				txt = skip_block(txt + 1, '{', '}');
				break;

			case '(':
				txt = skip_block(txt + 1, '(', ')');
				break;

			case '?':
				if (*++txt == '>')
					return txt + 1;
				break;

			default:
//printf(" <%c%c%c%c> ", *(txt+0), *(txt+1), *(txt+2), *(txt+3));
				if (isident(*txt)) {
					const char *ptr = txt-1;
					while (*++ptr && isident(*ptr)) ;
					int len = ptr - txt;

					if (len == 8 && strncasecmp(txt, "function", 8) == 0)
					{
						php_function(txt, class_name == "" ? lstPhpFunctions : lstPhpClasses, class_name, sorted);
					}
					else if (len == 5 && strncasecmp(txt, "class", 5) == 0)
					{
						php_class(txt, lstPhpClasses, class_name, sorted);
					}
					else
					{
						//printf("[[");for (const char* p=txt; p<ptr; p++)printf("%c", *p);printf(":%li]]", ptr - txt);
						txt = ptr;
					}
				}
				break;
		}
		txt++;
	}
//printf("\n");
	return txt;
} /* PhpScript */
Beispiel #20
0
/*! API: run tests. */
int main(int argc, char *argv[])
{
	plan(8);

	// Register service and signal handler
	struct sigaction sa;
	sa.sa_handler = interrupt_handle;
	sigemptyset(&sa.sa_mask);
	sa.sa_flags = 0;
	sigaction(SIGALRM, &sa, NULL); // Interrupt

	/* Initialize */
	srand(time(NULL));
	pthread_mutex_init(&_runnable_mx, NULL);
	pthread_mutex_init(&_destructor_mx, NULL);

	/* Test 1: Create unit */
	dt_unit_t *unit = dt_create(2, &runnable, NULL, NULL);
	ok(unit != NULL, "dthreads: create unit (size %d)", unit->size);
	if (unit == NULL) {
		skip_block(7, "No dthreads unit");
		goto skip_all;
	}

	/* Test 2: Start tasks. */
	_runnable_i = 0;
	ok(dt_start(unit) == 0, "dthreads: start single task");

	/* Test 3: Wait for tasks. */
	ok(dt_join(unit) == 0, "dthreads: join threads");

	/* Test 4: Compare counter. */
	int expected = _runnable_cycles * 2;
	is_int(expected, _runnable_i, "dthreads: result ok");

	/* Test 5: Deinitialize */
	dt_delete(&unit);
	ok(unit == NULL, "dthreads: delete unit");

	/* Test 6: Wrong values. */
	unit = dt_create(-1, NULL, NULL, NULL);
	ok(unit == NULL, "dthreads: create with negative count");

	/* Test 7: NULL operations crashing. */
	int ret = 0;
	ret += dt_activate(0);
	ret += dt_cancel(0);
	ret += dt_compact(0);
	dt_delete(0);
	ret += dt_is_cancelled(0);
	ret += dt_join(0);
	ret += dt_signalize(0, SIGALRM);
	ret += dt_start(0);
	ret += dt_stop(0);
	ret += dt_unit_lock(0);
	ret += dt_unit_unlock(0);
	is_int(-1098, ret, "dthreads: correct values when passed NULL context");

	/* Test 8: Thread destructor. */
	_destructor_data = 0;
	unit = dt_create(2, 0, destruct, 0);
	dt_start(unit);
	dt_stop(unit);
	dt_join(unit);
	is_int(2, _destructor_data, "dthreads: destructor with dt_create_coherent()");
	dt_delete(&unit);

skip_all:

	pthread_mutex_destroy(&_runnable_mx);
	pthread_mutex_destroy(&_destructor_mx);
	return 0;
}
Beispiel #21
0
Datei: edns.c Projekt: idtek/knot
static bool test_setters(knot_rrset_t *opt_rr, int *done)
{
	assert(opt_rr != NULL);
	assert(done != NULL);

	/* Header-related setters. */
	knot_edns_set_payload(opt_rr, E_MAX_PLD2);
	knot_edns_set_ext_rcode(opt_rr, E_RCODE2);
	knot_edns_set_version(opt_rr, E_VERSION2);
	knot_edns_set_do(opt_rr);

	bool success = true;
	bool check = check_header(opt_rr, E_MAX_PLD2, E_VERSION2, DO_FLAG,
	                          E_RCODE2, "OPT RR setters", done);
	success &= check;

	/* OPTION(RDATA)-related setters. */

	/* Proper option. */
	int ret = knot_edns_add_option(opt_rr, KNOT_EDNS_OPTION_NSID,
	                           E_NSID_LEN, (uint8_t *)E_NSID_STR, NULL);
	ok(ret == KNOT_EOK, "OPT RR setters: add option with data (ret = %s)",
	   knot_strerror(ret));
	(*done)++;

	/* Wrong argument: no OPT RR. */
	ret = knot_edns_add_option(NULL, E_OPT3_CODE, E_OPT3_FAKE_LEN,
	                           (uint8_t *)E_OPT3_FAKE_DATA, NULL);
	ok(ret == KNOT_EINVAL, "OPT RR setters: add option (rr == NULL) "
	   "(ret = %s)", knot_strerror(ret));
	(*done)++;

	/* Wrong argument: option length != 0 && data == NULL. */
	ret = knot_edns_add_option(opt_rr, E_OPT3_CODE, E_OPT3_FAKE_LEN, NULL,
	                           NULL);
	ok(ret == KNOT_EINVAL, "OPT RR setters: add option (data == NULL, "
	   "len != 0) (ret = %s)", knot_strerror(ret));
	(*done)++;

	/* Empty OPTION (length 0, data != NULL). */
	ret = knot_edns_add_option(opt_rr, E_OPT3_CODE, E_OPT3_LEN,
	                           (uint8_t *)E_OPT3_FAKE_DATA, NULL);
	ok(ret == KNOT_EOK, "OPT RR setters: add empty option 1 (ret = %s)",
	   knot_strerror(ret));
	(*done)++;

	/* Empty OPTION (length 0, data == NULL). */
	ret = knot_edns_add_option(opt_rr, E_OPT4_CODE, E_OPT4_LEN,
	                           (uint8_t *)E_OPT4_DATA, NULL);
	ok(ret == KNOT_EOK, "OPT RR setters: add empty option 2 (ret = %s)",
	   knot_strerror(ret));
	(*done)++;

	knot_rdata_t *rdata = knot_rdataset_at(&opt_rr->rrs, 0);
	if (rdata == NULL) {
		skip_block(2, "No RDATA in OPT RR.");
		return false;
	}

	/* Check proper option */
	check = check_option(rdata, KNOT_EDNS_OPTION_NSID, E_NSID_LEN,
	                     (uint8_t *)E_NSID_STR,
	                     "OPT RR setters (proper option)", done);
	success &= check;

	/* Check empty option 1 */
	check = check_option(rdata, E_OPT3_CODE, E_OPT3_LEN,
	                     (uint8_t *)E_OPT3_DATA,
	                     "OPT RR setters (empty option 1)", done);
	success &= check;

	/* Check empty option 2 */
	check = check_option(rdata, E_OPT4_CODE, E_OPT4_LEN,
	                     (uint8_t *)E_OPT4_DATA,
	                     "OPT RR setters (empty option 2)", done);
	success &= check;

	return success;
}
Beispiel #22
0
Datei: rrl.c Projekt: dnstap/knot
int main(int argc, char *argv[])
{
	plan(10);

	/* Prepare query. */
	knot_pkt_t *query = knot_pkt_new(NULL, 512, NULL);
	if (query == NULL) {
		return KNOT_ERROR; /* Fatal */
	}

	knot_dname_t *qname = knot_dname_from_str("beef.");
	int ret = knot_pkt_put_question(query, qname, KNOT_CLASS_IN, KNOT_RRTYPE_A);
	knot_dname_free(&qname, NULL);
	if (ret != KNOT_EOK) {
		knot_pkt_free(&query);
		return KNOT_ERROR; /* Fatal */
	}

	/* Prepare response */
	uint8_t rbuf[65535];
	size_t rlen = sizeof(rbuf);
	memcpy(rbuf, query->wire, query->size);
	knot_wire_flags_set_qr(rbuf);

	rrl_req_t rq;
	rq.w = rbuf;
	rq.len = rlen;
	rq.query = query;
	rq.flags = 0;

	/* 1. create rrl table */
	rrl_table_t *rrl = rrl_create(RRL_SIZE);
	ok(rrl != NULL, "rrl: create");

	/* 2. set rate limit */
	uint32_t rate = 10;
	rrl_setrate(rrl, rate);
	is_int(rate, rrl_rate(rrl), "rrl: setrate");

	/* 3. setlocks */
	ret = rrl_setlocks(rrl, RRL_LOCKS);
	is_int(KNOT_EOK, ret, "rrl: setlocks");

	/* 4. N unlimited requests. */
	conf_zone_t *zone_conf = malloc(sizeof(conf_zone_t));
	conf_init_zone(zone_conf);
	zone_conf->name = strdup("rrl.");
	zone_t *zone = zone_new(zone_conf);

	struct sockaddr_storage addr;
	struct sockaddr_storage addr6;
	sockaddr_set(&addr, AF_INET, "1.2.3.4", 0);
	sockaddr_set(&addr6, AF_INET6, "1122:3344:5566:7788::aabb", 0);
	ret = 0;
	for (unsigned i = 0; i < rate; ++i) {
		if (rrl_query(rrl, &addr, &rq, zone) != KNOT_EOK ||
		    rrl_query(rrl, &addr6, &rq, zone) != KNOT_EOK) {
			ret = KNOT_ELIMIT;
			break;
		}
	}
	is_int(0, ret, "rrl: unlimited IPv4/v6 requests");

#ifdef ENABLE_TIMED_TESTS
	/* 5. limited request */
	ret = rrl_query(rrl, &addr, &rq, zone);
	is_int(0, ret, "rrl: throttled IPv4 request");

	/* 6. limited IPv6 request */
	ret = rrl_query(rrl, &addr6, &rq, zone);
	is_int(0, ret, "rrl: throttled IPv6 request");
#else
	skip_block(2, "Timed tests not enabled");
#endif

	/* 7. invalid values. */
	ret = 0;
	rrl_create(0);            // NULL
	ret += rrl_setrate(0, 0); // 0
	ret += rrl_rate(0);       // 0
	ret += rrl_setlocks(0,0); // -1
	ret += rrl_query(0, 0, 0, 0); // -1
	ret += rrl_query(rrl, 0, 0, 0); // -1
	ret += rrl_query(rrl, (void*)0x1, 0, 0); // -1
	ret += rrl_destroy(0); // -1
	is_int(-488, ret, "rrl: not crashed while executing functions on NULL context");

#ifdef ENABLE_TIMED_TESTS
	/* 8. hopscotch test */
	struct runnable_data rd = {
		1, rrl, &addr, &rq, zone
	};
	rrl_hopscotch(&rd);
	ok(rd.passed, "rrl: hashtable is ~ consistent");

	/* 9. reseed */
	is_int(0, rrl_reseed(rrl), "rrl: reseed");

	/* 10. hopscotch after reseed. */
	rrl_hopscotch(&rd);
	ok(rd.passed, "rrl: hashtable is ~ consistent");
#else
	skip_block(3, "Timed tests not enabled");
#endif

	zone_free(&zone);
	knot_pkt_free(&query);
	rrl_destroy(rrl);
	return 0;
}
Beispiel #23
0
/*! Run all scheduled tests for given parameters.
 */
int main(int argc, char *argv[])
{
	plan(19);

	// Test 1: Allocate new config
	const char *config_fn = "rc:/sample_conf";
	conf_t *conf = conf_new(strdup(config_fn));
	ok(conf != 0, "config_new()");

	// Test 2: Parse config
	int ret = conf_parse_str(conf, sample_conf_rc);
	is_int(0, ret, "parsing configuration file %s", config_fn);
	if (ret != 0) {
		skip_block(19, "Parse err");
		goto skip_all;
	}

	// Test 3: Test server version (0-level depth)
	is_string("Infinitesimal", conf->version, "server version loaded ok");

	// Test 4: Test interfaces (1-level depth)
	ok(!EMPTY_LIST(conf->ifaces), "configured interfaces exist");

	// Test 5,6: Interfaces content (2-level depth)
	struct node *n = HEAD(conf->ifaces);
	conf_iface_t *iface = (conf_iface_t*)n;
	struct sockaddr_storage addr_ref;
	sockaddr_set(&addr_ref, AF_INET, "10.10.1.1", 53531);
	is_int(0, sockaddr_cmp(&iface->addr, &addr_ref), "interface0 address check");

	n = n->next;
	iface = (conf_iface_t*)n;
	sockaddr_set(&addr_ref, AF_INET6, "::0", 53);
	is_int(0, sockaddr_cmp(&iface->addr, &addr_ref), "interface1 address check");

	// Test 9,10: Check server key
	if (EMPTY_LIST(conf->keys)) {
		ok(0, "TSIG key algorithm check - NO KEY FOUND");
		ok(0, "TSIG key secret check - NO KEY FOUND");
	} else {
		knot_tsig_key_t *k = &((conf_key_t *)HEAD(conf->keys))->k;
		uint8_t decoded_secret[] = { 0x5a };

		ok(k->algorithm == KNOT_TSIG_ALG_HMAC_MD5,
		       "TSIG key algorithm check");
		ok(k->secret.size == sizeof(decoded_secret)
		   && memcmp(k->secret.data, decoded_secret,
			     sizeof(decoded_secret)) == 0,
		   "TSIG key secret check");
	}

	// Test 11,12,13,14,15,16,17,18: Check logging facilities
	ok(list_size(&conf->logs) == 4, "log facilites count check");
	n = HEAD(conf->logs);
	ok(!EMPTY_LIST(conf->logs), "log facilities not empty");

	conf_log_t *log = (conf_log_t*)n;
	node_t *nm = HEAD(log->map);
	conf_log_map_t *m = (conf_log_map_t*)nm;
	ok(log->type == LOGT_SYSLOG, "log0 is syslog");

	if (EMPTY_LIST(log->map)) {
		skip_block(5, "Empty list");
	} else {
		ok(m->source == LOG_ANY, "syslog first rule is ANY");
		int mask = LOG_UPTO(LOG_NOTICE);
		ok(m->prios == mask, "syslog mask is equal");
		nm = nm->next;
		m = (conf_log_map_t*)nm;
		ok(m != 0, "syslog has more than 1 rule");
		if (m == 0) {
			skip_block(2, "No mapping");
		} else {
			ok(m->source == LOG_ZONE, "syslog next rule is for zone");
			ok(m->prios == LOG_UPTO(LOG_INFO), "rule for zone is: info level");
		}
	}

	// Test 19,20: File facility checks
	n = n->next;
	log = (conf_log_t*)n;
	ok(n != 0, "log has next facility");
	if (n == 0) {
		skip("No mapping");
	} else {
		is_string("/var/log/knot/server.err", log->file, "log file matches");
	}

	// Test 21: Load key dname
	const char *sample_str = "key0.example.net";
	knot_dname_t *sample = knot_dname_from_str_alloc(sample_str);
	if (list_size(&conf->keys) > 0) {
		knot_tsig_key_t *k = &((conf_key_t *)HEAD(conf->keys))->k;
		ok(knot_dname_cmp(sample, k->name) == 0,
		   "TSIG key dname check");
	} else {
		ok(0, "TSIG key dname check - NO KEY FOUND");
	}
	knot_dname_free(&sample, NULL);

skip_all:

	// Deallocating config
	conf_free(conf);

	return 0;
}
Beispiel #24
0
int
main(void)
{
    struct script_config config;
    struct kerberos_config *krbconf;
    char *newpass, *date;
    struct passwd pwd;
    time_t now;

    /* Load the Kerberos principal and password from a file. */
    krbconf = kerberos_setup(TAP_KRB_NEEDS_PASSWORD);
    memset(&config, 0, sizeof(config));
    config.user = krbconf->username;
    config.password = krbconf->password;
    config.extra[0] = krbconf->userprinc;

    /*
     * Ensure we can expire the password.  Heimdal has a prompt for the
     * expiration time, so save that to use as a substitution in the script.
     */
    now = time(NULL) - 1;
    if (!kerberos_expire_password(krbconf->userprinc, now))
        skip_all("kadmin not configured or kadmin mismatch");
    date = bstrdup(ctime(&now));
    date[strlen(date) - 1] = '\0';
    config.extra[1] = date;

    /* Generate a testing krb5.conf file. */
    kerberos_generate_conf(krbconf->realm);

    /* Create a fake passwd struct for our user. */
    memset(&pwd, 0, sizeof(pwd));
    pwd.pw_name = krbconf->username;
    pwd.pw_uid = getuid();
    pwd.pw_gid = getgid();
    basprintf(&pwd.pw_dir, "%s/tmp", getenv("BUILD"));
    pam_set_pwd(&pwd);

    /*
     * We'll be changing the password to something new.  This needs to be
     * sufficiently random that it's unlikely to fall afoul of password
     * strength checking.
     */
    basprintf(&newpass, "ngh1,a%lu nn9af6", (unsigned long) getpid());
    config.newpass = newpass;

    plan_lazy();

    /* Default behavior. */
#ifdef HAVE_KRB5_HEIMDAL
    run_script("data/scripts/expired/basic-heimdal", &config);
    config.newpass = krbconf->password;
    config.password = newpass;
    kerberos_expire_password(krbconf->userprinc, now);
    run_script("data/scripts/expired/basic-heimdal-debug", &config);
#else
    run_script("data/scripts/expired/basic-mit", &config);
    config.newpass = krbconf->password;
    config.password = newpass;
    kerberos_expire_password(krbconf->userprinc, now);
    run_script("data/scripts/expired/basic-mit-debug", &config);
#endif

    /* Test again with PAM_SILENT, specified two ways. */
#ifdef HAVE_KRB5_HEIMDAL
    config.newpass = newpass;
    config.password = krbconf->password;
    kerberos_expire_password(krbconf->userprinc, now);
    run_script("data/scripts/expired/basic-heimdal-silent", &config);
    config.newpass = krbconf->password;
    config.password = newpass;
    kerberos_expire_password(krbconf->userprinc, now);
    run_script("data/scripts/expired/basic-heimdal-flag-silent", &config);
#else
    config.newpass = newpass;
    config.password = krbconf->password;
    kerberos_expire_password(krbconf->userprinc, now);
    run_script("data/scripts/expired/basic-mit-silent", &config);
    config.newpass = krbconf->password;
    config.password = newpass;
    kerberos_expire_password(krbconf->userprinc, now);
    run_script("data/scripts/expired/basic-mit-flag-silent", &config);
#endif

    /*
     * We can only run the remaining checks if we can suppress the Kerberos
     * library behavior of prompting for a new password when the password has
     * expired.
     */
#ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_CHANGE_PASSWORD_PROMPT

    /* Check the forced failure behavior. */
    run_script("data/scripts/expired/fail", &config);
    run_script("data/scripts/expired/fail-debug", &config);

    /* Defer the error to the account management check. */
    config.newpass = newpass;
    config.password = krbconf->password;
    config.authtok = krbconf->password;
    kerberos_expire_password(krbconf->userprinc, now);
    run_script("data/scripts/expired/defer", &config);
    config.newpass = krbconf->password;
    config.password = newpass;
    config.authtok = newpass;
    kerberos_expire_password(krbconf->userprinc, now);
    run_script("data/scripts/expired/defer-debug", &config);

#else /* !HAVE_KRB5_GET_INIT_CREDS_OPT_SET_CHANGE_PASSWORD_PROMPT */

    /* Mention that we skipped something for the record. */
    skip_block(4, "cannot disable library password prompting");

#endif /* HAVE_KRB5_GET_INIT_CREDS_OPT_SET_CHANGE_PASSWORD_PROMPT */

    /* In case we ran into some error, try to unexpire the password. */
    kerberos_expire_password(krbconf->userprinc, 0);

    free(date);
    free(newpass);
    free(pwd.pw_dir);
    return 0;
}
Beispiel #25
0
int
main(void)
{
    int flag, status;
    socklen_t flaglen;
    struct addrinfo *ai4, *ai6;
    struct addrinfo hints;
    char addr[INET6_ADDRSTRLEN];
    char *p;
    socket_type fd;
    static const char *port = "119";
    static const char *ipv6_addr = "FEDC:BA98:7654:3210:FEDC:BA98:7654:3210";

#ifndef HAVE_INET6
    skip_all("IPv6 not supported");
#endif

    /* Set up the plan. */
    plan(34);

    /* Get IPv4 and IPv6 sockaddrs to use for subsequent tests. */
    memset(&hints, 0, sizeof(hints));
    hints.ai_flags = AI_NUMERICHOST;
    hints.ai_socktype = SOCK_STREAM;
    status = getaddrinfo("127.0.0.1", port, &hints, &ai4);
    if (status != 0)
        bail("getaddrinfo on 127.0.0.1 failed: %s", gai_strerror(status));
    status = getaddrinfo(ipv6_addr, port, &hints, &ai6);
    if (status != 0)
        bail("getaddr on %s failed: %s", ipv6_addr, gai_strerror(status));

    /* Test network_sockaddr_sprint. */
    ok(network_sockaddr_sprint(addr, sizeof(addr), ai6->ai_addr),
       "sprint of IPv6 address");
    for (p = addr; *p != '\0'; p++)
        if (islower((unsigned char) *p))
            *p = toupper((unsigned char) *p);
    is_string(ipv6_addr, addr, "...with right results");

    /* Test network_sockaddr_port. */
    is_int(119, network_sockaddr_port(ai6->ai_addr), "sockaddr_port IPv6");

    /* Test network_sockaddr_equal. */
    ok(network_sockaddr_equal(ai6->ai_addr, ai6->ai_addr),
       "sockaddr_equal IPv6");
    ok(!network_sockaddr_equal(ai4->ai_addr, ai6->ai_addr),
       "...and not equal to IPv4");
    ok(!network_sockaddr_equal(ai6->ai_addr, ai4->ai_addr),
       "...other way around");
    freeaddrinfo(ai6);

    /* Test IPv4 mapped addresses. */
    status = getaddrinfo("::ffff:7f00:1", NULL, &hints, &ai6);
    if (status != 0)
        bail("getaddr on ::ffff:7f00:1 failed: %s", gai_strerror(status));
    ok(network_sockaddr_sprint(addr, sizeof(addr), ai6->ai_addr),
       "sprint of IPv4-mapped address");
    is_string("127.0.0.1", addr, "...with right IPv4 result");
    ok(network_sockaddr_equal(ai4->ai_addr, ai6->ai_addr),
       "sockaddr_equal of IPv4-mapped address");
    ok(network_sockaddr_equal(ai6->ai_addr, ai4->ai_addr),
       "...and other way around");
    freeaddrinfo(ai4);
    status = getaddrinfo("127.0.0.2", NULL, &hints, &ai4);
    if (status != 0)
        bail("getaddrinfo on 127.0.0.2 failed: %s", gai_strerror(status));
    ok(!network_sockaddr_equal(ai4->ai_addr, ai6->ai_addr),
       "...but not some other address");
    ok(!network_sockaddr_equal(ai6->ai_addr, ai4->ai_addr),
       "...and the other way around");
    freeaddrinfo(ai6);
    freeaddrinfo(ai4);

    /* Tests for network_addr_compare. */
    is_addr_compare(1, ipv6_addr,   ipv6_addr,     NULL);
    is_addr_compare(1, ipv6_addr,   ipv6_addr,     "128");
    is_addr_compare(1, ipv6_addr,   ipv6_addr,     "60");
    is_addr_compare(1, "::127",     "0:0::127",    "128");
    is_addr_compare(1, "::127",     "0:0::128",    "120");
    is_addr_compare(0, "::127",     "0:0::128",    "128");
    is_addr_compare(0, "::7fff",    "0:0::8000",   "113");
    is_addr_compare(1, "::7fff",    "0:0::8000",   "112");
    is_addr_compare(0, "::3:ffff",  "::2:ffff",    "120");
    is_addr_compare(0, "::3:ffff",  "::2:ffff",    "119");
    is_addr_compare(0, "ffff::1",   "7fff::1",     "1");
    is_addr_compare(1, "ffff::1",   "7fff::1",     "0");
    is_addr_compare(0, "fffg::1",   "fffg::1",     NULL);
    is_addr_compare(0, "ffff::1",   "7fff::1",     "-1");
    is_addr_compare(0, "ffff::1",   "ffff::1",     "-1");
    is_addr_compare(0, "ffff::1",   "ffff::1",     "129");

    /* Test setting various socket options. */
    fd = socket(PF_INET6, SOCK_STREAM, IPPROTO_IP);
    if (fd == INVALID_SOCKET)
        sysbail("cannot create socket");
    network_set_reuseaddr(fd);
#ifdef SO_REUSEADDR
    flag = 0;
    flaglen = sizeof(flag);
    is_int(0, getsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &flag, &flaglen),
           "Getting SO_REUSEADDR works");
    ok(flag, "...and it is set");
#else
    skip_block(2, "SO_REUSEADDR not supported");
#endif
    network_set_v6only(fd);
#ifdef IPV6_V6ONLY
    flag = 0;
    flaglen = sizeof(flag);
    is_int(0, getsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &flag, &flaglen),
           "Getting IPV6_V6ONLY works");
    ok(flag, "...and it is set");
#else
    skip_block(2, "IPV6_V6ONLY not supported");
#endif
    network_set_freebind(fd);
#ifdef IP_FREEBIND
    flag = 0;
    flaglen = sizeof(flag);
    is_int(0, getsockopt(fd, IPPROTO_IP, IP_FREEBIND, &flag, &flaglen),
           "Getting IP_FREEBIND works");
    ok(flag, "...and it is set");
#else
    skip_block(2, "IP_FREEBIND not supported");
#endif
    close(fd);

    return 0;
}
Beispiel #26
0
bool CJSourceParser::ParseArguments( char*& cur )
{
    // DANGER-MACROS::

    // now cursor position is right after the first opening bracket
    // of the function declaration

    char* blocks    [16]; // used exclusivelly for iterative "lean out"
                          // of macros and misc. not-obviouse grammar
                          // (dirty,, but we cannot do it very nice,
                          //  we're not preprocessor-free C/C++ code)
    int   blockSizes[16];

    do
    {
        size_t blocksSkipped = 0;

        get_next_token( cur );

        bool first_blk = true;

        while( *cur != ')' && *cur != ',' )
        {
            blocks[blocksSkipped] = cur;

            if ( first_blk )
            {
                char* prev = cur;
                skip_token( cur );

                blockSizes[blocksSkipped] = size_t(cur-prev);

                first_blk = 0;
            }
            else
                blockSizes[blocksSkipped] = skip_block( cur );

            get_next_token( cur );
            ++blocksSkipped;
        }


        if ( blocksSkipped == 1 )
        {
            // check if the empty arg. list stressed with "void" inside
            if ( cmp_tokens_fast( blocks[0] , "void", 4 ) )
            {
                cur++;  // skip ')'

                break;
            }

            // FIXME:: TBD:: K&R-style function declarations!

            // if only one block enclosed, than it's probably
            // some macro, there should be at least two blocks,
            // one for argument type and another for it's identifier
            return false;
        }

        if ( blocksSkipped == 0 )
        {
            if ( *cur == 10 ) ++_gLineNo;
            ++cur; // skip ')'

            break; // function without paramters
        }

        // we should be in the operation context now
        spOperation* pOp = (spOperation*)mpCurCtx;

        spParameter* pPar = new spParameter();

        pOp->AddMember( pPar );
        // FOR NOW:: line number is not exact if argument list is mutiline
        pPar->mSrcLineNo = get_line_no();

        size_t nameBlock = blocksSkipped - 1;
        size_t typeBlock = nameBlock - 1;

        // check if default values present
        if ( *blocks[typeBlock] == '=' )
        {
            // expressions like "int = 5" are ignored,
            // since name for paramters is required
            if ( blocksSkipped == 3 )
            {
                if ( *cur == ')' )
                {
                    ++cur;
                    break;
                }
            else
                continue;
            }

            pPar->m_InitVal = wxString( blocks[nameBlock], blockSizes[nameBlock] );

            nameBlock = nameBlock - 2; // skip '=' token and default value block
            typeBlock = nameBlock - 1;
        }

        // attach comments about the parameter
        AttachComments( *pPar, blocks[nameBlock] );

        // retrieve argument name
        pPar->m_Name = wxString( blocks[nameBlock], blockSizes[nameBlock] );

        // retreive argument type

        size_t len = blockSizes[ typeBlock ];
        len = size_t ( (blocks[ typeBlock ] + len) - blocks[ 0 ] );

        pPar->m_Type = wxString( blocks[0], len );

        arrange_indirection_tokens_between( pPar->m_Type, pPar->m_Name );

        if ( *cur == ')' )
        {
            ++cur;
            break;
        }

        ++cur; // skip comma
        get_next_token(cur);

    } while(1);

    // skip possible whitespace between ')' and following "const"
    while ( isspace(*cur) )
        cur++;

    // check if it was really a function not a macro,
    // if so, than it should be terminated with semicolon ';'
    // or opening implemenetaton bracket '{'

    char* tok = cur;

    int tmpLnNo;
    store_line_no( tmpLnNo );

    bool result = true;

    do
    {
        if ( *tok == '{' || *tok == ';' )
        {
            restore_line_no(tmpLnNo);
            break;
        }

        // check for unexpected tokens
        if ( *tok == '=' || *tok == '0' )
        {
            skip_token(tok);
            if ( !get_next_token(tok) ) return false;
            continue;
        }

        if ( *tok == '}' ) return false;

        // if initialization list found
        if ( *tok == ':' )
        {
            restore_line_no(tmpLnNo);
            break;
        }

        if ( cmp_tokens_fast( tok, "const", 5 ) )
        {
            ((spOperation*)mpCurCtx)->mIsConstant = true;

            skip_token(tok);
            if ( !get_next_token(tok) ) return false;
            continue;
        }

        if ( CheckVisibilty( tok ) ) return false;

        // if next context found
        if ( is_keyword( tok ) ) return false;

        skip_token(tok);
        if ( !get_next_token(tok) ) return false;

    } while(1);

    return result;
}
Beispiel #27
0
/*
 * Test connect timeouts using IPv4.  Bring up a server on port 11119 on the
 * loopback address and test connections to it.  The server only accepts one
 * connection at a time, so a subsequent connection will time out.
 */
static void
test_timeout_ipv4(void)
{
    socket_type fd, c;
    pid_t child;
    socket_type block[20];
    int i, err;

    /*
     * Create the listening socket.  We set the listening queue size to 1,
     * but some operating systems, including Linux, will allow more
     * connection attempts to succeed than the backlog size.  We'll therefore
     * have to hammer this server with connections to try to get it to fail.
     */
    fd = network_bind_ipv4(SOCK_STREAM, "127.0.0.1", 11119);
    if (fd == INVALID_SOCKET)
        sysbail("cannot create or bind socket");
    if (listen(fd, 1) < 0)
        sysbail("cannot listen to socket");

    /* Fork off a child that just runs accept once and then sleeps. */
    child = fork();
    if (child < 0)
        sysbail("cannot fork");
    else if (child == 0) {
        alarm(10);
        c = accept(fd, NULL, 0);
        if (c == INVALID_SOCKET)
            _exit(1);
        sleep(9);
        _exit(0);
    }

    /* In the parent.  Open that first connection. */
    socket_close(fd);
    c = network_connect_host("127.0.0.1", 11119, NULL, 1);
    ok(c != INVALID_SOCKET, "Timeout: first connection worked");

    /*
     * It can take up to fifteen connections on Linux before connections start
     * actually timing out, and sometimes they never do.
     */
    alarm(20);
    for (i = 0; i < (int) ARRAY_SIZE(block); i++) {
        block[i] = network_connect_host("127.0.0.1", 11119, NULL, 1);
        if (block[i] == INVALID_SOCKET)
            break;
    }
    err = socket_errno;

    /*
     * If we reached the end of the array, we can't force a connection
     * timeout, so just skip this test.  It's also possible that the
     * connection will fail with ECONNRESET or ECONNREFUSED if the nine second
     * sleep in the child passed, so skip in that case as well.  Otherwise,
     * expect a failure due to timeout in a reasonable amount of time (less
     * than our 20-second alarm).
     */
    if (i == ARRAY_SIZE(block))
        skip_block(2, "short listen queue does not prevent connections");
    else {
        diag("Finally timed out on socket %d", i);
        ok(block[i] == INVALID_SOCKET, "Later connection timed out");
        if (err == ECONNRESET || err == ECONNREFUSED)
            skip("connections rejected without timeout");
        else
            is_int(ETIMEDOUT, err, "...with correct error code");
    }
    alarm(0);

    /* Shut down the client and clean up resources. */
    kill(child, SIGTERM);
    waitpid(child, NULL, 0);
    socket_close(c);
    for (i--; i >= 0; i--)
        if (block[i] != INVALID_SOCKET)
            socket_close(block[i]);
    socket_close(fd);
}
Beispiel #28
0
int
main(void)
{
    struct rule rule = {
        NULL, 0, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, 0, 0, NULL,
        NULL, NULL
    };
    const char *acls[5];

    plan(78);
    if (chdir(getenv("C_TAP_SOURCE")) < 0)
        sysbail("can't chdir to C_TAP_SOURCE");

    rule.file = (char *) "TEST";
    rule.acls = (char **) acls;
    acls[0] = "data/acl-simple";
    acls[1] = NULL;
    acls[2] = NULL;
    acls[3] = NULL;
    acls[4] = NULL;

    ok(acl_permit(&rule, "*****@*****.**"), "simple 1");
    ok(acl_permit(&rule, "*****@*****.**"), "simple 2");
    ok(acl_permit(&rule, "*****@*****.**"), "simple 3");
    ok(acl_permit(&rule, "*****@*****.**"), "simple 4");
    ok(acl_permit(&rule, "*****@*****.**"), "simple 5");

    ok(!acl_permit(&rule, "*****@*****.**"), "no 1");
    ok(!acl_permit(&rule, "*****@*****.**"), "no 2");
    ok(!acl_permit(&rule, "*****@*****.**"), "no 3");
    ok(!acl_permit(&rule, "*****@*****.**"), "no 4");

    /* Okay, now capture and check the errors. */
    acls[0] = "data/acl-bad-include";
    acls[1] = "data/acls/valid";
    errors_capture();
    ok(!acl_permit(&rule, "*****@*****.**"), "included file not found");
    is_string("data/acl-bad-include:1: included file data/acl-nosuchfile"
              " not found\n", errors, "...and correct error message");
    acls[0] = "data/acl-recursive";
    errors_capture();
    ok(!acl_permit(&rule, "*****@*****.**"), "recursive ACL inclusion");
    is_string("data/acl-recursive:3: data/acl-recursive recursively"
              " included\n", errors, "...and correct error message");
    acls[0] = "data/acls/valid-2";
    acls[1] = "data/acl-too-long";
    errors_capture();
    ok(acl_permit(&rule, "*****@*****.**"),
       "granted access based on first ACL file");
    ok(errors == NULL, "...with no errors");
    ok(!acl_permit(&rule, "*****@*****.**"),
       "...but failed when we hit second file with long line");
    is_string("data/acl-too-long:1: ACL file line too long\n", errors,
              "...with correct error message");
    acls[0] = "data/acl-no-such-file";
    acls[1] = "data/acls/valid";
    errors_capture();
    ok(!acl_permit(&rule, "*****@*****.**"), "no such ACL file");
    is_string("TEST:0: included file data/acl-no-such-file not found\n",
              errors, "...with correct error message");
    errors_capture();
    ok(!acl_permit(&rule, "*****@*****.**"),
       "...even with a principal in an ACL file");
    is_string("TEST:0: included file data/acl-no-such-file not found\n",
              errors, "...still with right error message");
    acls[0] = "data/acl-bad-syntax";
    errors_capture();
    ok(!acl_permit(&rule, "*****@*****.**"), "incorrect syntax");
    is_string("data/acl-bad-syntax:2: parse error\n", errors,
              "...with correct error message");
    errors_uncapture();

    /* Check that file: works at the top level. */
    acls[0] = "file:data/acl-simple";
    acls[1] = NULL;
    ok(acl_permit(&rule, "*****@*****.**"), "file: success");
    ok(!acl_permit(&rule, "*****@*****.**"), "file: failure");

    /* Check that include syntax works. */
    ok(acl_permit(&rule, "*****@*****.**"), "include 1");
    ok(acl_permit(&rule, "*****@*****.**"), "include 2");
    ok(acl_permit(&rule, "*****@*****.**"), "include 3");
    ok(acl_permit(&rule, "*****@*****.**"), "include 4");
    ok(acl_permit(&rule, "*****@*****.**"), "include 5");
    ok(!acl_permit(&rule, "*****@*****.**"), "include failure");

    /* Check that princ: works at the top level. */
    acls[0] = "princ:[email protected]";
    ok(acl_permit(&rule, "*****@*****.**"), "princ: success");
    ok(!acl_permit(&rule, "*****@*****.**"), "princ: failure");

    /* Check that deny: works at the top level. */
    acls[0] = "deny:princ:[email protected]";
    acls[1] = "princ:[email protected]";
    acls[2] = "princ:[email protected]";
    acls[3] = NULL;
    ok(acl_permit(&rule, "*****@*****.**"), "deny: success");
    ok(!acl_permit(&rule, "*****@*****.**"), "deny: failure");

    /* And make sure deny interacts correctly with files. */
    acls[0] = "data/acl-simple";
    acls[1] = "princ:[email protected]";
    acls[2] = NULL;
    ok(!acl_permit(&rule, "*****@*****.**"),
       "deny in file beats later princ");
    acls[0] = "deny:princ:[email protected]";
    acls[1] = "data/acl-simple";
    ok(!acl_permit(&rule, "*****@*****.**"), "deny overrides later file");

    /*
     * Ensure deny never affirmatively grants access, so deny:deny: matches
     * nothing.
     */
    acls[0] = "deny:deny:princ:[email protected]";
    acls[1] = "data/acl-simple";
    ok(acl_permit(&rule, "*****@*****.**"), "deny:deny does nothing");
    ok(acl_permit(&rule, "*****@*****.**"),
       "deny:deny doesn't break anything");

    /*
     * Denying a file denies anything that would match the file, and nothing
     * that wouldn't, including due to an embedded deny.
     */
    acls[0] = "deny:file:data/acl-simple";
    acls[1] = "princ:[email protected]";
    acls[2] = "princ:[email protected]";
    acls[3] = "princ:[email protected]";
    acls[4] = NULL;
    ok(!acl_permit(&rule, "*****@*****.**"), "deny of a file works");
    ok(acl_permit(&rule, "*****@*****.**"),
       "...and doesn't break anything");
    ok(acl_permit(&rule, "*****@*****.**"),
       "...and deny inside a denied file is ignored");

    /* Check for an invalid ACL scheme. */
    acls[0] = "ihateyou:verymuch";
    acls[1] = "data/acls/valid";
    errors_capture();
    ok(!acl_permit(&rule, "*****@*****.**"), "invalid ACL scheme");
    is_string("TEST:0: invalid ACL scheme 'ihateyou'\n", errors,
              "...with correct error");
    errors_uncapture();

    /*
     * Check GPUT ACLs, or make sure they behave sanely when GPUT support is
     * not compiled.
     */
    server_config_set_gput_file((char *) "data/gput");
    acls[0] = "gput:test";
    acls[1] = NULL;
#ifdef HAVE_GPUT
    ok(acl_permit(&rule, "*****@*****.**"), "GPUT 1");
    ok(!acl_permit(&rule, "*****@*****.**"), "GPUT 2");
    ok(!acl_permit(&rule, "*****@*****.**"), "GPUT 3");
    acls[0] = "gput:test[%@EXAMPLE.NET]";
    ok(acl_permit(&rule, "*****@*****.**"), "GPUT with transform 1");
    ok(!acl_permit(&rule, "*****@*****.**"), "GPUT with transform 2");
    ok(!acl_permit(&rule, "*****@*****.**"), "GPUT with transform 3");
#else
    errors_capture();
    ok(!acl_permit(&rule, "*****@*****.**"), "GPUT");
    is_string("TEST:0: ACL scheme 'gput' is not supported\n", errors,
              "...with not supported error");
    errors_uncapture();
    skip_block(4, "GPUT support not configured");
#endif

    /*
     * Check PCRE ACLs, or make sure they behave as they should when not
     * supported.
     */
    acls[0] = "deny:pcre:host/foo.+\\.org@EXAMPLE\\.ORG";
    acls[1] = "pcre:host/.+\\.org@EXAMPLE\\.ORG";
    acls[2] = NULL;
#ifdef HAVE_PCRE
    ok(acl_permit(&rule, "host/[email protected]"), "PCRE 1");
    ok(!acl_permit(&rule, "host/[email protected]"), "PCRE 2");
    ok(!acl_permit(&rule, "host/[email protected]"), "PCRE 3");
    ok(!acl_permit(&rule, "host/[email protected]"), "PCRE 4 (plus operator)");
    ok(!acl_permit(&rule, "host/[email protected]"),
       "PCRE 5 (escaped period)");
    acls[1] = "pcre:+host/.*";
    errors_capture();
    ok(!acl_permit(&rule, "host/[email protected]"), "PCRE invalid regex");
    is_string("TEST:0: compilation of regex '+host/.*' failed around 0\n",
              errors, "...with invalid regex error");
    errors_uncapture();
#else
    errors_capture();
    ok(!acl_permit(&rule, "host/[email protected]"), "PCRE");
    is_string("TEST:0: ACL scheme 'pcre' is not supported\n", errors,
              "...with not supported error");
    errors_uncapture();
    skip_block(5, "PCRE support not configured");
#endif

    /*
     * Check POSIX regex ACLs, or make sure they behave as they should when
     * not supported.
     */
    acls[0] = "deny:regex:host/foo.*\\.org@EXAMPLE\\.ORG";
    acls[1] = "regex:host/.*\\.org@EXAMPLE\\.ORG";
    acls[2] = NULL;
#ifdef HAVE_REGCOMP
    ok(acl_permit(&rule, "host/[email protected]"), "regex 1");
    ok(!acl_permit(&rule, "host/[email protected]"), "regex 2");
    ok(!acl_permit(&rule, "host/[email protected]"), "regex 3");
    ok(acl_permit(&rule, "host/[email protected]"), "regex 4");
    ok(!acl_permit(&rule, "host/[email protected]"),
       "regex 5 (escaped period)");
    acls[1] = "regex:*host/.*";
    errors_capture();
    ok(!acl_permit(&rule, "host/[email protected]"), "regex invalid regex");
    ok(strncmp(errors, "TEST:0: compilation of regex '*host/.*' failed:",
               strlen("TEST:0: compilation of regex '*host/.*' failed:")) == 0,
       "...with invalid regex error");
    errors_uncapture();
    free(errors);
    errors = NULL;
#else
    errors_capture();
    ok(!acl_permit(&rule, "host/[email protected]"), "regex");
    is_string("TEST:0: ACL scheme 'regex' is not supported\n", errors,
              "...with not supported error");
    errors_uncapture();
    skip_block(5, "regex support not available");
    free(errors);
    errors = NULL;
#endif

    /* Test for valid characters in ACL files. */
    acls[0] = "file:data/acls";
    acls[1] = NULL;
    ok(acl_permit(&rule, "*****@*****.**"), "valid chars 1");
    ok(acl_permit(&rule, "*****@*****.**"), "valid chars 2");
    ok(acl_permit(&rule, "*****@*****.**"), "valid chars 3");
    ok(!acl_permit(&rule, "*****@*****.**"), "invalid chars 1");
    ok(!acl_permit(&rule, "*****@*****.**"), "invalid chars 2");
    ok(!acl_permit(&rule, "*****@*****.**"), "invalid chars 3");

    /* Check anyuser:*. */
    acls[0] = "anyuser:auth";
    acls[1] = NULL;
    ok(acl_permit(&rule, "*****@*****.**"), "anyuser:auth");
    acls[0] = "anyuser:anonymous";
    ok(acl_permit(&rule, "*****@*****.**"), "anyuser:anonymous");
    acls[0] = "ANYUSER";
    ok(acl_permit(&rule, "*****@*****.**"), "ANYUSER");

    /*
     * Ensure that anyuser:auth and ANYUSER don't allow the anonymous
     * identity, but anyuser:anonymous does.
     */
    acls[0] = "anyuser:auth";
    acls[1] = NULL;
    ok(!acl_permit_anonymous(&rule), "anyuser:auth disallows anonymous");
    acls[0] = "ANYUSER";
    ok(!acl_permit_anonymous(&rule), "ANYUSER disallows anonymous");
    acls[0] = "anyuser:anonymous";
    ok(acl_permit_anonymous(&rule), "anyuser:anonymous allows anonymous");

    /* Check error handling of unknown anyuser ACLs. */
    acls[0] = "anyuser:foo";
    acls[1] = NULL;
    errors_capture();
    ok(!acl_permit(&rule, "*****@*****.**"), "invalid anyuser ACL");
    is_string("TEST:0: invalid ACL value 'anyuser:foo'\n", errors,
              "...with correct error.");
    errors_uncapture();
    free(errors);
    errors = NULL;

    return 0;
}
Beispiel #29
0
int
main(void)
{
    pam_handle_t *pamh;
    struct pam_args *args;
    struct pam_conv conv = { NULL, NULL };
    bool status;
    struct vector *cells;
    char *program;
    struct output *seen;
    const char *argv_bool[2] = { NULL, NULL };
    const char *argv_err[2] = { NULL, NULL };
    const char *argv_empty[] = { NULL };
#ifdef HAVE_KRB5
    const char *argv_all[] = {
        "cells=stanford.edu,ir.stanford.edu", "debug", "expires=1d",
        "ignore_root", "minimum_uid=1000", "program=/bin/true"
    };
    char *krb5conf;
#else
    const char *argv_all[] = {
        "cells=stanford.edu,ir.stanford.edu", "debug", "expires=86400",
        "ignore_root", "minimum_uid=1000", "program=/bin/true"
    };
#endif

    if (pam_start("test", NULL, &conv, &pamh) != PAM_SUCCESS)
        sysbail("cannot create pam_handle_t");
    args = putil_args_new(pamh, 0);
    if (args == NULL)
        bail("cannot create PAM argument struct");

    plan(161);

    /* First, check just the defaults. */
    args->config = config_new();
    status = putil_args_defaults(args, options, optlen);
    ok(status, "Setting the defaults");
    ok(args->config->cells == NULL, "...cells default");
    is_int(false, args->config->debug, "...debug default");
    is_int(10, args->config->expires, "...expires default");
    is_int(true, args->config->ignore_root, "...ignore_root default");
    is_int(0, args->config->minimum_uid, "...minimum_uid default");
    ok(args->config->program == NULL, "...program default");

    /* Now parse an empty set of PAM arguments.  Nothing should change. */
    status = putil_args_parse(args, 0, argv_empty, options, optlen);
    ok(status, "Parse of empty argv");
    ok(args->config->cells == NULL, "...cells still default");
    is_int(false, args->config->debug, "...debug still default");
    is_int(10, args->config->expires, "...expires default");
    is_int(true, args->config->ignore_root, "...ignore_root still default");
    is_int(0, args->config->minimum_uid, "...minimum_uid still default");
    ok(args->config->program == NULL, "...program still default");

    /* Now, check setting everything. */
    status = putil_args_parse(args, 6, argv_all, options, optlen);
    ok(status, "Parse of full argv");
    if (args->config->cells == NULL)
        ok_block(4, false, "...cells is set");
    else {
        ok(args->config->cells != NULL, "...cells is set");
        is_int(2, args->config->cells->count, "...with two cells");
        is_string("stanford.edu", args->config->cells->strings[0],
                  "...first is stanford.edu");
        is_string("ir.stanford.edu", args->config->cells->strings[1],
                  "...second is ir.stanford.edu");
    }
    is_int(true, args->config->debug, "...debug is set");
    is_int(86400, args->config->expires, "...expires is set");
    is_int(true, args->config->ignore_root, "...ignore_root is set");
    is_int(1000, args->config->minimum_uid, "...minimum_uid is set");
    is_string("/bin/true", args->config->program, "...program is set");
    config_free(args->config);
    args->config = NULL;

    /* Test deep copying of defaults. */
    cells = vector_new();
    if (cells == NULL)
        sysbail("cannot allocate memory");
    vector_add(cells, "foo.com");
    vector_add(cells, "bar.com");
    options[0].defaults.list = cells;
    program = strdup("/bin/false");
    if (program == NULL)
        sysbail("cannot allocate memory");
    options[5].defaults.string = program;
    args->config = config_new();
    status = putil_args_defaults(args, options, optlen);
    ok(status, "Setting defaults with new defaults");
    if (args->config->cells == NULL)
        ok_block(4, false, "...cells is set");
    else {
        ok(args->config->cells != NULL, "...cells is set");
        is_int(2, args->config->cells->count, "...with two cells");
        is_string("foo.com", args->config->cells->strings[0],
                  "...first is foo.com");
        is_string("bar.com", args->config->cells->strings[1],
                  "...second is bar.com");
    }
    is_string("/bin/false", args->config->program,
              "...program is /bin/false");
    status = putil_args_parse(args, 6, argv_all, options, optlen);
    ok(status, "Parse of full argv after defaults");
    if (args->config->cells == NULL)
        ok_block(4, false, "...cells is set");
    else {
        ok(args->config->cells != NULL, "...cells is set");
        is_int(2, args->config->cells->count, "...with two cells");
        is_string("stanford.edu", args->config->cells->strings[0],
                  "...first is stanford.edu");
        is_string("ir.stanford.edu", args->config->cells->strings[1],
                  "...second is ir.stanford.edu");
    }
    is_int(true, args->config->debug, "...debug is set");
    is_int(86400, args->config->expires, "...expires is set");
    is_int(true, args->config->ignore_root, "...ignore_root is set");
    is_int(1000, args->config->minimum_uid, "...minimum_uid is set");
    is_string("/bin/true", args->config->program, "...program is set");
    is_string("foo.com", cells->strings[0], "...first cell after parse");
    is_string("bar.com", cells->strings[1], "...second cell after parse");
    is_string("/bin/false", program, "...string after parse");
    config_free(args->config);
    args->config = NULL;
    is_string("foo.com", cells->strings[0], "...first cell after free");
    is_string("bar.com", cells->strings[1], "...second cell after free");
    is_string("/bin/false", program, "...string after free");
    options[0].defaults.list = NULL;
    options[5].defaults.string = NULL;
    vector_free(cells);
    free(program);

    /* Test specifying the default for a vector parameter as a string. */
    options[0].type = TYPE_STRLIST;
    options[0].defaults.string = "foo.com,bar.com";
    args->config = config_new();
    status = putil_args_defaults(args, options, optlen);
    ok(status, "Setting defaults with string default for vector");
    if (args->config->cells == NULL)
        ok_block(4, false, "...cells is set");
    else {
        ok(args->config->cells != NULL, "...cells is set");
        is_int(2, args->config->cells->count, "...with two cells");
        is_string("foo.com", args->config->cells->strings[0],
                  "...first is foo.com");
        is_string("bar.com", args->config->cells->strings[1],
                  "...second is bar.com");
    }
    config_free(args->config);
    args->config = NULL;
    options[0].type = TYPE_LIST;
    options[0].defaults.string = NULL;

    /* Should be no errors so far. */
    ok(pam_output() == NULL, "No errors so far");

    /* Test various ways of spelling booleans. */
    args->config = config_new();
    TEST_BOOL("debug", args->config->debug, true);
    TEST_BOOL("debug=false", args->config->debug, false);
    TEST_BOOL("debug=true", args->config->debug, true);
    TEST_BOOL("debug=no", args->config->debug, false);
    TEST_BOOL("debug=yes", args->config->debug, true);
    TEST_BOOL("debug=off", args->config->debug, false);
    TEST_BOOL("debug=on", args->config->debug, true);
    TEST_BOOL("debug=0", args->config->debug, false);
    TEST_BOOL("debug=1", args->config->debug, true);
    TEST_BOOL("debug=False", args->config->debug, false);
    TEST_BOOL("debug=trUe", args->config->debug, true);
    TEST_BOOL("debug=No", args->config->debug, false);
    TEST_BOOL("debug=Yes", args->config->debug, true);
    TEST_BOOL("debug=OFF", args->config->debug, false);
    TEST_BOOL("debug=ON", args->config->debug, true);
    config_free(args->config);
    args->config = NULL;

    /* Test for various parsing errors. */
    args->config = config_new();
    TEST_ERROR("debug=", LOG_ERR,
               "invalid boolean in setting: debug=");
    TEST_ERROR("debug=truth", LOG_ERR,
               "invalid boolean in setting: debug=truth");
    TEST_ERROR("minimum_uid", LOG_ERR,
               "value missing for option minimum_uid");
    TEST_ERROR("minimum_uid=", LOG_ERR,
               "value missing for option minimum_uid=");
    TEST_ERROR("minimum_uid=foo", LOG_ERR,
               "invalid number in setting: minimum_uid=foo");
    TEST_ERROR("minimum_uid=1000foo", LOG_ERR,
               "invalid number in setting: minimum_uid=1000foo");
    TEST_ERROR("program", LOG_ERR, "value missing for option program");
    TEST_ERROR("cells", LOG_ERR, "value missing for option cells");
    config_free(args->config);
    args->config = NULL;

#ifdef HAVE_KRB5

    /* Test for Kerberos krb5.conf option parsing. */
    krb5conf = test_file_path("data/krb5-pam.conf");
    if (krb5conf == NULL)
        bail("cannot find data/krb5-pam.conf");
    if (setenv("KRB5_CONFIG", krb5conf, 1) < 0)
        sysbail("cannot set KRB5_CONFIG");
    krb5_free_context(args->ctx);
    status = krb5_init_context(&args->ctx);
    if (status != 0)
        bail("cannot parse test krb5.conf file");
    args->config = config_new();
    status = putil_args_defaults(args, options, optlen);
    ok(status, "Setting the defaults");
    status = putil_args_krb5(args, "testing", options, optlen);
    ok(status, "Options from krb5.conf");
    ok(args->config->cells == NULL, "...cells default");
    is_int(true, args->config->debug, "...debug set from krb5.conf");
    is_int(1800, args->config->expires, "...expires set from krb5.conf");
    is_int(true, args->config->ignore_root, "...ignore_root default");
    is_int(1000, args->config->minimum_uid,
           "...minimum_uid set from krb5.conf");
    ok(args->config->program == NULL, "...program default");
    status = putil_args_krb5(args, "other-test", options, optlen);
    ok(status, "Options from krb5.conf (other-test)");
    is_int(-1000, args->config->minimum_uid,
           "...minimum_uid set from krb5.conf other-test");

    /* Test with a realm set, which should expose more settings. */
    krb5_free_context(args->ctx);
    status = krb5_init_context(&args->ctx);
    if (status != 0)
        bail("cannot parse test krb5.conf file");
    args->realm = strdup("FOO.COM");
    if (args->realm == NULL)
        sysbail("cannot allocate memory");
    status = putil_args_krb5(args, "testing", options, optlen);
    ok(status, "Options from krb5.conf with FOO.COM");
    is_int(2, args->config->cells->count, "...cells count from krb5.conf");
    is_string("foo.com", args->config->cells->strings[0],
              "...first cell from krb5.conf");
    is_string("bar.com", args->config->cells->strings[1],
              "...second cell from krb5.conf");
    is_int(true, args->config->debug, "...debug set from krb5.conf");
    is_int(1800, args->config->expires, "...expires set from krb5.conf");
    is_int(true, args->config->ignore_root, "...ignore_root default");
    is_int(1000, args->config->minimum_uid,
           "...minimum_uid set from krb5.conf");
    is_string("/bin/false", args->config->program,
              "...program from krb5.conf");

    /* Test with a different realm. */
    free(args->realm);
    args->realm = strdup("BAR.COM");
    if (args->realm == NULL)
        sysbail("cannot allocate memory");
    status = putil_args_krb5(args, "testing", options, optlen);
    ok(status, "Options from krb5.conf with BAR.COM");
    is_int(2, args->config->cells->count, "...cells count from krb5.conf");
    is_string("bar.com", args->config->cells->strings[0],
              "...first cell from krb5.conf");
    is_string("foo.com", args->config->cells->strings[1],
              "...second cell from krb5.conf");
    is_int(true, args->config->debug, "...debug set from krb5.conf");
    is_int(1800, args->config->expires, "...expires set from krb5.conf");
    is_int(true, args->config->ignore_root, "...ignore_root default");
    is_int(1000, args->config->minimum_uid,
           "...minimum_uid set from krb5.conf");
    is_string("echo /bin/true", args->config->program,
              "...program from krb5.conf");
    config_free(args->config);
    args->config = config_new();
    status = putil_args_krb5(args, "other-test", options, optlen);
    ok(status, "Options from krb5.conf (other-test with realm)");
    ok(args->config->cells == NULL, "...cells is NULL");
    is_string("echo /bin/true", args->config->program,
              "...program from krb5.conf");
    config_free(args->config);
    args->config = NULL;

    /* Test for time parsing errors. */
    args->config = config_new();
    TEST_ERROR("expires=ft87", LOG_ERR,
               "bad time value in setting: expires=ft87");
    config_free(args->config);

    /* Test error reporting from the krb5.conf parser. */
    args->config = config_new();
    status = putil_args_krb5(args, "bad-number", options, optlen);
    ok(status, "Options from krb5.conf (bad-number)");
    seen = pam_output();
    is_string("invalid number in krb5.conf setting for minimum_uid: 1000foo",
              seen->lines[0].line, "...and correct error reported");
    is_int(LOG_ERR, seen->lines[0].priority, "...with correct priority");
    pam_output_free(seen);
    config_free(args->config);
    args->config = NULL;

    /* Test error reporting on times from the krb5.conf parser. */
    args->config = config_new();
    status = putil_args_krb5(args, "bad-time", options, optlen);
    ok(status, "Options from krb5.conf (bad-time)");
    seen = pam_output();
    if (seen == NULL)
        ok_block(2, false, "...no error output");
    else {
        is_string("invalid time in krb5.conf setting for expires: ft87",
                  seen->lines[0].line, "...and correct error reported");
        is_int(LOG_ERR, seen->lines[0].priority, "...with correct priority");
    }
    pam_output_free(seen);
    config_free(args->config);
    args->config = NULL;

    test_file_path_free(krb5conf);

#else /* !HAVE_KRB5 */

    skip_block(37, "Kerberos support not configured");

#endif

    putil_args_free(args);
    pam_end(pamh, 0);
    return 0;
}