1115619Sdes/*-
2115619Sdes * Copyright (c) 2003 Networks Associates Technology, Inc.
3228690Sdes * Copyright (c) 2004-2011 Dag-Erling Sm��rgrav
4115619Sdes * All rights reserved.
5115619Sdes *
6115619Sdes * This software was developed for the FreeBSD Project by ThinkSec AS and
7115619Sdes * Network Associates Laboratories, the Security Research Division of
8115619Sdes * Network Associates, Inc.  under DARPA/SPAWAR contract N66001-01-C-8035
9115619Sdes * ("CBOSS"), as part of the DARPA CHATS research program.
10115619Sdes *
11115619Sdes * Redistribution and use in source and binary forms, with or without
12115619Sdes * modification, are permitted provided that the following conditions
13115619Sdes * are met:
14115619Sdes * 1. Redistributions of source code must retain the above copyright
15115619Sdes *    notice, this list of conditions and the following disclaimer.
16115619Sdes * 2. Redistributions in binary form must reproduce the above copyright
17115619Sdes *    notice, this list of conditions and the following disclaimer in the
18115619Sdes *    documentation and/or other materials provided with the distribution.
19115619Sdes * 3. The name of the author may not be used to endorse or promote
20115619Sdes *    products derived from this software without specific prior written
21115619Sdes *    permission.
22115619Sdes *
23115619Sdes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
24115619Sdes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25115619Sdes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26115619Sdes * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
27115619Sdes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28115619Sdes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29115619Sdes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30115619Sdes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31115619Sdes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32115619Sdes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33115619Sdes * SUCH DAMAGE.
34115619Sdes *
35255376Sdes * $Id: openpam_readline.c 703 2013-08-16 11:57:54Z des $
36115619Sdes */
37115619Sdes
38228690Sdes#ifdef HAVE_CONFIG_H
39228690Sdes# include "config.h"
40228690Sdes#endif
41228690Sdes
42115619Sdes#include <stdio.h>
43115619Sdes#include <stdlib.h>
44115619Sdes
45115619Sdes#include <security/pam_appl.h>
46236099Sdes
47115619Sdes#include "openpam_impl.h"
48115619Sdes
49115619Sdes#define MIN_LINE_LENGTH 128
50115619Sdes
51115619Sdes/*
52115619Sdes * OpenPAM extension
53115619Sdes *
54115619Sdes * Read a line from a file.
55115619Sdes */
56115619Sdes
57115619Sdeschar *
58115619Sdesopenpam_readline(FILE *f, int *lineno, size_t *lenp)
59115619Sdes{
60168463Sdes	char *line;
61115619Sdes	size_t len, size;
62115619Sdes	int ch;
63115619Sdes
64247809Sdes	line = NULL;
65247809Sdes	if (openpam_straddch(&line, &size, &len, 0) != 0)
66115619Sdes		return (NULL);
67115619Sdes	for (;;) {
68115619Sdes		ch = fgetc(f);
69115619Sdes		/* strip comment */
70115619Sdes		if (ch == '#') {
71115619Sdes			do {
72115619Sdes				ch = fgetc(f);
73115619Sdes			} while (ch != EOF && ch != '\n');
74115619Sdes		}
75115619Sdes		/* eof */
76115619Sdes		if (ch == EOF) {
77228690Sdes			/* done */
78115619Sdes			break;
79115619Sdes		}
80115619Sdes		/* eol */
81115619Sdes		if (ch == '\n') {
82115619Sdes			if (lineno != NULL)
83115619Sdes				++*lineno;
84115619Sdes			/* skip blank lines */
85115619Sdes			if (len == 0)
86115619Sdes				continue;
87115619Sdes			/* continuation */
88115619Sdes			if (line[len - 1] == '\\') {
89115619Sdes				line[--len] = '\0';
90228690Sdes				continue;
91115619Sdes			}
92228690Sdes			/* done */
93228690Sdes			break;
94115619Sdes		}
95115619Sdes		/* anything else */
96236099Sdes		if (openpam_straddch(&line, &size, &len, ch) != 0)
97236099Sdes			goto fail;
98115619Sdes	}
99228690Sdes	if (len == 0)
100228690Sdes		goto fail;
101115619Sdes	if (lenp != NULL)
102115619Sdes		*lenp = len;
103115619Sdes	return (line);
104228690Sdesfail:
105115619Sdes	FREE(line);
106115619Sdes	return (NULL);
107115619Sdes}
108115619Sdes
109115619Sdes/**
110236099Sdes * DEPRECATED openpam_readlinev
111236099Sdes *
112115619Sdes * The =openpam_readline function reads a line from a file, and returns it
113236099Sdes * in a NUL-terminated buffer allocated with =!malloc.
114115619Sdes *
115115619Sdes * The =openpam_readline function performs a certain amount of processing
116228690Sdes * on the data it reads:
117115619Sdes *
118236099Sdes *  - Comments (introduced by a hash sign) are stripped.
119236099Sdes *
120228690Sdes *  - Blank lines are ignored.
121236099Sdes *
122228690Sdes *  - If a line ends in a backslash, the backslash is stripped and the
123228690Sdes *    next line is appended.
124228690Sdes *
125115619Sdes * If =lineno is not =NULL, the integer variable it points to is
126115619Sdes * incremented every time a newline character is read.
127115619Sdes *
128115619Sdes * If =lenp is not =NULL, the length of the line (not including the
129115619Sdes * terminating NUL character) is stored in the variable it points to.
130115619Sdes *
131115619Sdes * The caller is responsible for releasing the returned buffer by passing
132236099Sdes * it to =!free.
133236099Sdes *
134236099Sdes * >openpam_readlinev
135236099Sdes * >openpam_readword
136115619Sdes */
137