2 * Copyright (c) 2012 Dag-Erling Smørgrav
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote
14 * products derived from this software without specific prior written
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * $Id: t_openpam_readword.c 648 2013-03-05 17:54:27Z des $
42 #include <security/pam_appl.h>
43 #include <security/openpam.h>
48 * Read a word from the temp file and verify that the result matches our
49 * expectations: whether a word was read at all, how many lines were read
50 * (in case of quoted or escaped newlines), whether we reached the end of
51 * the file and whether we reached the end of the line.
54 orw_expect(struct t_file *tf, const char *expected, int lines, int eof, int eol)
60 got = openpam_readword(tf->file, &lineno, &len);
62 err(1, "%s(): %s", __func__, tf->name);
63 if (expected != NULL && got == NULL) {
64 t_verbose("expected <<%s>>, got nothing\n", expected);
67 if (expected == NULL && got != NULL) {
68 t_verbose("expected nothing, got <<%s>>\n", got);
71 if (expected != NULL && got != NULL && strcmp(expected, got) != 0) {
72 t_verbose("expected <<%s>>, got <<%s>>\n", expected, got);
75 if (lineno != lines) {
76 t_verbose("expected to advance %d lines, advanced %d lines\n",
80 if (eof && !t_feof(tf)) {
81 t_verbose("expected EOF, but didn't get it\n");
84 if (!eof && t_feof(tf)) {
85 t_verbose("didn't expect EOF, but got it anyway\n");
90 err(1, "%s(): %s", __func__, tf->name);
91 if (eol && ch != '\n') {
92 t_verbose("expected EOL, but didn't get it\n");
95 if (!eol && ch == '\n') {
96 t_verbose("didn't expect EOL, but got it anyway\n");
100 ungetc(ch, tf->file);
105 /***************************************************************************
106 * Lines without words
109 T_FUNC(empty_input, "empty input")
115 ret = orw_expect(tf, NULL, 0 /*lines*/, 1 /*eof*/, 0 /*eol*/);
120 T_FUNC(empty_line, "empty line")
128 ret = orw_expect(tf, NULL, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
133 T_FUNC(unterminated_line, "unterminated line")
141 ret = orw_expect(tf, NULL, 0 /*lines*/, 1 /*eof*/, 0 /*eol*/);
146 T_FUNC(single_whitespace, "single whitespace")
152 t_fprintf(tf, " \n");
154 ret = orw_expect(tf, NULL, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
159 T_FUNC(multiple_whitespace, "multiple whitespace")
165 t_fprintf(tf, " \t\r\n");
167 ret = orw_expect(tf, NULL, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
172 T_FUNC(comment, "comment")
178 t_fprintf(tf, "# comment\n");
180 ret = orw_expect(tf, NULL, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
185 T_FUNC(whitespace_before_comment, "whitespace before comment")
191 t_fprintf(tf, " # comment\n");
193 ret = orw_expect(tf, NULL, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
199 /***************************************************************************
200 * Simple cases - no quotes or escapes
203 T_FUNC(single_word, "single word")
205 const char *word = "hello";
210 t_fprintf(tf, "%s\n", word);
212 ret = orw_expect(tf, word, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
217 T_FUNC(single_whitespace_before_word, "single whitespace before word")
219 const char *word = "hello";
224 t_fprintf(tf, " %s\n", word);
226 ret = orw_expect(tf, word, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
231 T_FUNC(double_whitespace_before_word, "double whitespace before word")
233 const char *word = "hello";
238 t_fprintf(tf, " %s\n", word);
240 ret = orw_expect(tf, word, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
245 T_FUNC(single_whitespace_after_word, "single whitespace after word")
247 const char *word = "hello";
252 t_fprintf(tf, "%s \n", word);
254 ret = orw_expect(tf, word, 0 /*lines*/, 0 /*eof*/, 0 /*eol*/);
259 T_FUNC(double_whitespace_after_word, "double whitespace after word")
261 const char *word = "hello";
266 t_fprintf(tf, "%s \n", word);
268 ret = orw_expect(tf, word, 0 /*lines*/, 0 /*eof*/, 0 /*eol*/);
273 T_FUNC(comment_after_word, "comment after word")
275 const char *word = "hello";
280 t_fprintf(tf, "%s # comment\n", word);
282 ret = orw_expect(tf, word, 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
283 orw_expect(tf, NULL, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
288 T_FUNC(word_containing_hash, "word containing hash")
290 const char *word = "hello#world";
295 t_fprintf(tf, "%s\n", word);
297 ret = orw_expect(tf, word, 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
302 T_FUNC(two_words, "two words")
304 const char *word[] = { "hello", "world" };
309 t_fprintf(tf, "%s %s\n", word[0], word[1]);
311 ret = orw_expect(tf, word[0], 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
312 orw_expect(tf, word[1], 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
318 /***************************************************************************
322 T_FUNC(naked_escape, "naked escape")
330 ret = orw_expect(tf, NULL, 0 /*lines*/, 1 /*eof*/, 0 /*eol*/);
335 T_FUNC(escaped_escape, "escaped escape")
341 t_fprintf(tf, "\\\\\n");
343 ret = orw_expect(tf, "\\", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
348 T_FUNC(escaped_whitespace, "escaped whitespace")
354 t_fprintf(tf, "\\ \\\t \\\r \\\n\n");
356 ret = orw_expect(tf, " ", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
357 orw_expect(tf, "\t", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
358 orw_expect(tf, "\r", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
359 /* this last one is a line continuation */
360 orw_expect(tf, NULL, 1 /*lines*/, 0 /*eof*/, 1 /*eol*/);
365 T_FUNC(escaped_newline_before_word, "escaped newline before word")
371 t_fprintf(tf, "\\\nhello world\n");
373 ret = orw_expect(tf, "hello", 1 /*lines*/, 0 /*eof*/, 0 /*eol*/);
378 T_FUNC(escaped_newline_within_word, "escaped newline within word")
384 t_fprintf(tf, "hello\\\nworld\n");
386 ret = orw_expect(tf, "helloworld", 1 /*lines*/, 0 /*eof*/, 1 /*eol*/);
391 T_FUNC(escaped_newline_after_word, "escaped newline after word")
397 t_fprintf(tf, "hello\\\n world\n");
399 ret = orw_expect(tf, "hello", 1 /*lines*/, 0 /*eof*/, 0 /*eol*/);
404 T_FUNC(escaped_letter, "escaped letter")
410 t_fprintf(tf, "\\z\n");
412 ret = orw_expect(tf, "z", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
418 /***************************************************************************
422 T_FUNC(naked_single_quote, "naked single quote")
430 ret = orw_expect(tf, NULL, 0 /*lines*/, 1 /*eof*/, 0 /*eol*/);
435 T_FUNC(naked_double_quote, "naked double quote")
443 ret = orw_expect(tf, NULL, 0 /*lines*/, 1 /*eof*/, 0 /*eol*/);
448 T_FUNC(empty_single_quotes, "empty single quotes")
454 t_fprintf(tf, "''\n");
456 ret = orw_expect(tf, "", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
461 T_FUNC(empty_double_quotes, "empty double quotes")
467 t_fprintf(tf, "\"\"\n");
469 ret = orw_expect(tf, "", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
474 T_FUNC(single_quotes_within_double_quotes, "single quotes within double quotes")
480 t_fprintf(tf, "\"' '\"\n");
482 ret = orw_expect(tf, "' '", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
487 T_FUNC(double_quotes_within_single_quotes, "double quotes within single quotes")
493 t_fprintf(tf, "'\" \"'\n");
495 ret = orw_expect(tf, "\" \"", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
500 T_FUNC(single_quoted_whitespace, "single-quoted whitespace")
506 t_fprintf(tf, "' ' '\t' '\r' '\n'\n");
508 ret = orw_expect(tf, " ", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
509 orw_expect(tf, "\t", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
510 orw_expect(tf, "\r", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
511 orw_expect(tf, "\n", 1 /*lines*/, 0 /*eof*/, 1 /*eol*/);
516 T_FUNC(double_quoted_whitespace, "double-quoted whitespace")
522 t_fprintf(tf, "\" \" \"\t\" \"\r\" \"\n\"\n");
524 ret = orw_expect(tf, " ", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
525 orw_expect(tf, "\t", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
526 orw_expect(tf, "\r", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
527 orw_expect(tf, "\n", 1 /*lines*/, 0 /*eof*/, 1 /*eol*/);
532 T_FUNC(single_quoted_words, "single-quoted words")
538 t_fprintf(tf, "'hello world'\n");
540 ret = orw_expect(tf, "hello world", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
545 T_FUNC(double_quoted_words, "double-quoted words")
551 t_fprintf(tf, "\"hello world\"\n");
553 ret = orw_expect(tf, "hello world", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
559 /***************************************************************************
560 * Combinations of quoted and unquoted text
563 T_FUNC(single_quote_before_word, "single quote before word")
569 t_fprintf(tf, "'hello 'world\n");
571 ret = orw_expect(tf, "hello world", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
576 T_FUNC(double_quote_before_word, "double quote before word")
582 t_fprintf(tf, "\"hello \"world\n");
584 ret = orw_expect(tf, "hello world", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
589 T_FUNC(single_quote_within_word, "single quote within word")
595 t_fprintf(tf, "hello' 'world\n");
597 ret = orw_expect(tf, "hello world", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
602 T_FUNC(double_quote_within_word, "double quote within word")
608 t_fprintf(tf, "hello\" \"world\n");
610 ret = orw_expect(tf, "hello world", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
615 T_FUNC(single_quote_after_word, "single quote after word")
621 t_fprintf(tf, "hello' world'\n");
623 ret = orw_expect(tf, "hello world", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
628 T_FUNC(double_quote_after_word, "double quote after word")
634 t_fprintf(tf, "hello\" world\"\n");
636 ret = orw_expect(tf, "hello world", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
642 /***************************************************************************
643 * Combinations of escape and quotes
646 T_FUNC(escaped_single_quote,
647 "escaped single quote")
653 t_fprintf(tf, "\\'\n");
655 ret = orw_expect(tf, "'", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
660 T_FUNC(escaped_double_quote,
661 "escaped double quote")
667 t_fprintf(tf, "\\\"\n");
669 ret = orw_expect(tf, "\"", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
674 T_FUNC(escaped_whitespace_within_single_quotes,
675 "escaped whitespace within single quotes")
681 t_fprintf(tf, "'\\ ' '\\\t' '\\\r' '\\\n'\n");
683 ret = orw_expect(tf, "\\ ", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
684 orw_expect(tf, "\\\t", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
685 orw_expect(tf, "\\\r", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
686 orw_expect(tf, "\\\n", 1 /*lines*/, 0 /*eof*/, 1 /*eol*/);
691 T_FUNC(escaped_whitespace_within_double_quotes,
692 "escaped whitespace within double quotes")
698 t_fprintf(tf, "\"\\ \" \"\\\t\" \"\\\r\" \"\\\n\"\n");
700 ret = orw_expect(tf, "\\ ", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
701 orw_expect(tf, "\\\t", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
702 orw_expect(tf, "\\\r", 0 /*lines*/, 0 /*eof*/, 0 /*eol*/) &&
703 /* this last one is a line continuation */
704 orw_expect(tf, "", 1 /*lines*/, 0 /*eof*/, 1 /*eol*/);
709 T_FUNC(escaped_letter_within_single_quotes,
710 "escaped letter within single quotes")
716 t_fprintf(tf, "'\\z'\n");
718 ret = orw_expect(tf, "\\z", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
723 T_FUNC(escaped_letter_within_double_quotes,
724 "escaped letter within double quotes")
730 t_fprintf(tf, "\"\\z\"\n");
732 ret = orw_expect(tf, "\\z", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
737 T_FUNC(escaped_escape_within_single_quotes,
738 "escaped escape within single quotes")
744 t_fprintf(tf, "'\\\\'\n");
746 ret = orw_expect(tf, "\\\\", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
751 T_FUNC(escaped_escape_within_double_quotes,
752 "escaped escape within double quotes")
758 t_fprintf(tf, "\"\\\\\"\n");
760 ret = orw_expect(tf, "\\", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
765 T_FUNC(escaped_single_quote_within_single_quotes,
766 "escaped single quote within single quotes")
772 t_fprintf(tf, "'\\''\n");
774 ret = orw_expect(tf, NULL, 1 /*lines*/, 1 /*eof*/, 0 /*eol*/);
779 T_FUNC(escaped_double_quote_within_single_quotes,
780 "escaped double quote within single quotes")
786 t_fprintf(tf, "'\\\"'\n");
788 ret = orw_expect(tf, "\\\"", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
793 T_FUNC(escaped_single_quote_within_double_quotes,
794 "escaped single quote within double quotes")
800 t_fprintf(tf, "\"\\'\"\n");
802 ret = orw_expect(tf, "\\'", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
807 T_FUNC(escaped_double_quote_within_double_quotes,
808 "escaped double quote within double quotes")
814 t_fprintf(tf, "\"\\\"\"\n");
816 ret = orw_expect(tf, "\"", 0 /*lines*/, 0 /*eof*/, 1 /*eol*/);
822 /***************************************************************************
826 static const struct t_test *t_plan[] = {
829 T(single_whitespace),
830 T(multiple_whitespace),
832 T(whitespace_before_comment),
835 T(single_whitespace_before_word),
836 T(double_whitespace_before_word),
837 T(single_whitespace_after_word),
838 T(double_whitespace_after_word),
839 T(comment_after_word),
840 T(word_containing_hash),
845 T(escaped_whitespace),
846 T(escaped_newline_before_word),
847 T(escaped_newline_within_word),
848 T(escaped_newline_after_word),
851 T(naked_single_quote),
852 T(naked_double_quote),
853 T(empty_single_quotes),
854 T(empty_double_quotes),
855 T(single_quotes_within_double_quotes),
856 T(double_quotes_within_single_quotes),
857 T(single_quoted_whitespace),
858 T(double_quoted_whitespace),
859 T(single_quoted_words),
860 T(double_quoted_words),
862 T(single_quote_before_word),
863 T(double_quote_before_word),
864 T(single_quote_within_word),
865 T(double_quote_within_word),
866 T(single_quote_after_word),
867 T(double_quote_after_word),
869 T(escaped_single_quote),
870 T(escaped_double_quote),
871 T(escaped_whitespace_within_single_quotes),
872 T(escaped_whitespace_within_double_quotes),
873 T(escaped_letter_within_single_quotes),
874 T(escaped_letter_within_double_quotes),
875 T(escaped_escape_within_single_quotes),
876 T(escaped_escape_within_double_quotes),
877 T(escaped_single_quote_within_single_quotes),
878 T(escaped_double_quote_within_single_quotes),
879 T(escaped_single_quote_within_double_quotes),
880 T(escaped_double_quote_within_double_quotes),
885 const struct t_test **
886 t_prepare(int argc, char *argv[])