Exemplo n.º 1
0
/*
 * Read a word from the temp file and verify that the result matches our
 * expectations: whether a word was read at all, how many lines were read
 * (in case of quoted or escaped newlines), whether we reached the end of
 * the file and whether we reached the end of the line.
 */
static int
orw_expect(struct t_file *tf, const char *expected, int lines, int eof, int eol)
{
	int ch, lineno = 0;
	char *got;
	size_t len;

	got = openpam_readword(tf->file, &lineno, &len);
	if (t_ferror(tf))
		err(1, "%s(): %s", __func__, tf->name);
	if (expected != NULL && got == NULL) {
		t_verbose("expected <<%s>>, got nothing\n", expected);
		return (0);
	}
	if (expected == NULL && got != NULL) {
		t_verbose("expected nothing, got <<%s>>\n", got);
		return (0);
	}
	if (expected != NULL && got != NULL && strcmp(expected, got) != 0) {
		t_verbose("expected <<%s>>, got <<%s>>\n", expected, got);
		return (0);
	}
	if (lineno != lines) {
		t_verbose("expected to advance %d lines, advanced %d lines\n",
		    lines, lineno);
		return (0);
	}
	if (eof && !t_feof(tf)) {
		t_verbose("expected EOF, but didn't get it\n");
		return (0);
	}
	if (!eof && t_feof(tf)) {
		t_verbose("didn't expect EOF, but got it anyway\n");
		return (0);
	}
	ch = fgetc(tf->file);
	if (t_ferror(tf))
		err(1, "%s(): %s", __func__, tf->name);
	if (eol && ch != '\n') {
		t_verbose("expected EOL, but didn't get it\n");
		return (0);
	}
	if (!eol && ch == '\n') {
		t_verbose("didn't expect EOL, but got it anyway\n");
		return (0);
	}
	if (ch != EOF)
		ungetc(ch, tf->file);
	return (1);
}
Exemplo n.º 2
0
/*
 * Read a line from the temp file and verify that the result matches our
 * expectations: whether a line was read at all, how many and which words
 * it contained, how many lines were read (in case of quoted or escaped
 * newlines) and whether we reached the end of the file.
 */
static int
orlv_expect(const char **expectedv, int lines, int eof)
{
	int expectedc, gotc, i, lineno = 0;
	char **gotv;

	expectedc = 0;
	if (expectedv != NULL)
		while (expectedv[expectedc] != NULL)
			++expectedc;
	gotv = openpam_readlinev(f, &lineno, &gotc);
	if (ferror(f))
		err(1, "%s(): %s", __func__, filename);
	if (expectedv != NULL && gotv == NULL) {
		t_verbose("expected %d words, got nothing\n", expectedc);
		return (0);
	}
	if (expectedv == NULL && gotv != NULL) {
		t_verbose("expected nothing, got %d words\n", gotc);
		FREEV(gotc, gotv);
		return (0);
	}
	if (expectedv != NULL && gotv != NULL) {
		if (expectedc != gotc) {
			t_verbose("expected %d words, got %d\n",
			    expectedc, gotc);
			FREEV(gotc, gotv);
			return (0);
		}
		for (i = 0; i < gotc; ++i) {
			if (strcmp(expectedv[i], gotv[i]) != 0) {
				t_verbose("word %d: expected <<%s>>, "
				    "got <<%s>>\n", i, expectedv[i], gotv[i]);
				FREEV(gotc, gotv);
				return (0);
			}
		}
		FREEV(gotc, gotv);
	}
	if (lineno != lines) {
		t_verbose("expected to advance %d lines, advanced %d lines\n",
		    lines, lineno);
		return (0);
	}
	if (eof && !feof(f)) {
		t_verbose("expected EOF, but didn't get it\n");
		return (0);
	}
	if (!eof && feof(f)) {
		t_verbose("didn't expect EOF, but got it anyway\n");
		return (0);
	}
	return (1);
}
Exemplo n.º 3
0
/*
 * Conversation function
 *
 * The appdata argument points to a struct t_pam_conv_script which
 * contains both the expected messages and the desired responses.  If
 * script.responses is NULL, t_pam_conv() will return PAM_CONV_ERR.  If an
 * error occurs (incorrect number of messages, messages don't match script
 * etc.), script.comment will be set to point to a malloc()ed string
 * describing the error.  Otherwise, t_pam_conv() will return to its
 * caller a malloc()ed copy of script.responses.
 */
int
t_pam_conv(int nm, const struct pam_message **msgs,
    struct pam_response **respsp, void *ad)
{
	struct t_pam_conv_script *s = ad;
	struct pam_response *resps;
	int i;

	/* check message count */
	if (nm != s->nmsg) {
		asprintf(&s->comment, "expected %d messages, got %d",
		    s->nmsg, nm);
		return (PAM_CONV_ERR);
	}
	if (nm <= 0 || nm > PAM_MAX_NUM_MSG) {
		/* since the previous test passed, this is intentional! */
		s->comment = NULL;
		return (PAM_CONV_ERR);
	}

	/* check each message and provide the sed answer */
	if ((resps = calloc(nm, sizeof *resps)) == NULL)
		goto enomem;
	for (i = 0; i < nm; ++i) {
		if (msgs[i]->msg_style != s->msgs[i].msg_style) {
			asprintf(&s->comment,
			    "message %d expected style %d got %d", i,
			    s->msgs[i].msg_style, msgs[i]->msg_style);
			goto fail;
		}
		if (strcmp(msgs[i]->msg, s->msgs[i].msg) != 0) {
			asprintf(&s->comment,
			    "message %d expected \"%s\" got \"%s\"", i,
			    s->msgs[i].msg, msgs[i]->msg);
			goto fail;
		}
		switch (msgs[i]->msg_style) {
		case PAM_PROMPT_ECHO_OFF:
			t_verbose("[PAM_PROMPT_ECHO_OFF] %s\n", msgs[i]->msg);
			break;
		case PAM_PROMPT_ECHO_ON:
			t_verbose("[PAM_PROMPT_ECHO_ON] %s\n", msgs[i]->msg);
			break;
		case PAM_ERROR_MSG:
			t_verbose("[PAM_ERROR_MSG] %s\n", msgs[i]->msg);
			break;
		case PAM_TEXT_INFO:
			t_verbose("[PAM_TEXT_INFO] %s\n", msgs[i]->msg);
			break;
		default:
			asprintf(&s->comment, "invalid message style %d",
			    msgs[i]->msg_style);
			goto fail;
		}
		/* copy the response, if there is one */
		if (s->resps[i].resp != NULL &&
		    (resps[i].resp = strdup(s->resps[i].resp)) == NULL)
			goto enomem;
		resps[i].resp_retcode = s->resps[i].resp_retcode;
	}
	s->comment = NULL;
	*respsp = resps;
	return (PAM_SUCCESS);
enomem:
	asprintf(&s->comment, "%s", strerror(ENOMEM));
fail:
	for (i = 0; i < nm; ++i)
		free(resps[i].resp);
	free(resps);
	return (PAM_CONV_ERR);
}