2 * Copyright (c) 2002-2003 Networks Associates Technology, Inc.
5 * This software was developed for the FreeBSD Project by ThinkSec AS and
6 * Network Associates Laboratories, the Security Research Division of
7 * Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035
8 * ("CBOSS"), as part of the DARPA CHATS research program.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. The name of the author may not be used to endorse or promote
19 * products derived from this software without specific prior written
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * $P4: //depot/projects/openpam/lib/openpam_ttyconv.c#26 $
37 #include <sys/types.h>
49 #include <security/pam_appl.h>
51 #include "openpam_impl.h"
53 int openpam_ttyconv_timeout
= 0;
63 prompt(const char *msg
)
65 char buf
[PAM_MAX_RESP_SIZE
];
66 struct sigaction action
, saved_action
;
67 sigset_t saved_sigset
, sigset
;
68 unsigned int saved_alarm
;
75 sigaddset(&sigset
, SIGINT
);
76 sigaddset(&sigset
, SIGTSTP
);
77 sigprocmask(SIG_SETMASK
, &sigset
, &saved_sigset
);
78 action
.sa_handler
= &timeout
;
80 sigemptyset(&action
.sa_mask
);
81 sigaction(SIGALRM
, &action
, &saved_action
);
90 if (openpam_ttyconv_timeout
>= 0)
91 saved_alarm
= alarm(openpam_ttyconv_timeout
);
93 for (len
= 0; ch
!= '\n' && !eof
&& !error
; ++len
) {
94 switch (read(fd
, &ch
, 1)) {
96 if (len
< PAM_MAX_RESP_SIZE
- 1) {
109 if (openpam_ttyconv_timeout
>= 0)
111 sigaction(SIGALRM
, &saved_action
, NULL
);
112 sigprocmask(SIG_SETMASK
, &saved_sigset
, NULL
);
113 if (openpam_ttyconv_timeout
>= 0)
116 fputs(" timeout!", stderr
);
119 memset(buf
, 0, sizeof(buf
));
122 /* trim trailing whitespace */
123 for (len
= strlen(buf
); len
> 0; --len
)
124 if (buf
[len
- 1] != '\r' && buf
[len
- 1] != '\n')
127 retval
= strdup(buf
);
128 memset(buf
, 0, sizeof(buf
));
133 prompt_echo_off(const char *msg
)
135 struct termios tattr
;
141 if (tcgetattr(fd
, &tattr
) != 0) {
142 openpam_log(PAM_LOG_ERROR
, "tcgetattr(): %m");
145 lflag
= tattr
.c_lflag
;
146 tattr
.c_lflag
&= ~ECHO
;
147 if (tcsetattr(fd
, TCSAFLUSH
, &tattr
) != 0) {
148 openpam_log(PAM_LOG_ERROR
, "tcsetattr(): %m");
152 tattr
.c_lflag
= lflag
;
153 (void)tcsetattr(fd
, TCSANOW
, &tattr
);
162 * Simple tty-based conversation function
166 openpam_ttyconv(int n
,
167 const struct pam_message
**msg
,
168 struct pam_response
**resp
,
171 struct pam_response
*aresp
;
176 if (n
<= 0 || n
> PAM_MAX_NUM_MSG
)
177 RETURNC(PAM_CONV_ERR
);
178 if ((aresp
= calloc(n
, sizeof *aresp
)) == NULL
)
179 RETURNC(PAM_BUF_ERR
);
180 for (i
= 0; i
< n
; ++i
) {
181 aresp
[i
].resp_retcode
= 0;
182 aresp
[i
].resp
= NULL
;
183 switch (msg
[i
]->msg_style
) {
184 case PAM_PROMPT_ECHO_OFF
:
185 aresp
[i
].resp
= prompt_echo_off(msg
[i
]->msg
);
186 if (aresp
[i
].resp
== NULL
)
189 case PAM_PROMPT_ECHO_ON
:
190 aresp
[i
].resp
= prompt(msg
[i
]->msg
);
191 if (aresp
[i
].resp
== NULL
)
195 fputs(msg
[i
]->msg
, stderr
);
196 if (strlen(msg
[i
]->msg
) > 0 &&
197 msg
[i
]->msg
[strlen(msg
[i
]->msg
) - 1] != '\n')
201 fputs(msg
[i
]->msg
, stdout
);
202 if (strlen(msg
[i
]->msg
) > 0 &&
203 msg
[i
]->msg
[strlen(msg
[i
]->msg
) - 1] != '\n')
211 RETURNC(PAM_SUCCESS
);
213 for (i
= 0; i
< n
; ++i
) {
214 if (aresp
[i
].resp
!= NULL
) {
215 memset(aresp
[i
].resp
, 0, strlen(aresp
[i
].resp
));
219 memset(aresp
, 0, n
* sizeof *aresp
);
222 RETURNC(PAM_CONV_ERR
);
234 * The =openpam_ttyconv function is a standard conversation function
235 * suitable for use on TTY devices.
236 * It should be adequate for the needs of most text-based interactive
239 * The =openpam_ttyconv function allows the application to specify a
240 * timeout for user input by setting the global integer variable
241 * :openpam_ttyconv_timeout to the length of the timeout in seconds.