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); }
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; }
/* 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); }
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 */
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; }
/** * 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 */
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; }
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; }
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); }
/* 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"); } }
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 ); }
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 */
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; }
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(©); 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; }
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 */
/*! 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; }
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; }
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; }
/*! 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; }
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; }
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; }
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; }
/* * 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); }
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; }
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; }