1/*
2 * Copyright (c) 1999-2005, 2007, 2010
3 *	Todd C. Miller <Todd.Miller@courtesan.com>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
17 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
18 *
19 * Sponsored in part by the Defense Advanced Research Projects
20 * Agency (DARPA) and Air Force Research Laboratory, Air Force
21 * Materiel Command, USAF, under agreement number F39502-99-1-0512.
22 */
23
24#include <config.h>
25
26#include <sys/types.h>
27#include <sys/param.h>
28#include <stdio.h>
29#ifdef STDC_HEADERS
30# include <stdlib.h>
31# include <stddef.h>
32#else
33# ifdef HAVE_STDLIB_H
34#  include <stdlib.h>
35# endif
36#endif /* STDC_HEADERS */
37#ifdef HAVE_STRING_H
38# include <string.h>
39#endif /* HAVE_STRING_H */
40#ifdef HAVE_STRINGS_H
41# include <strings.h>
42#endif /* HAVE_STRINGS_H */
43#ifdef HAVE_UNISTD_H
44# include <unistd.h>
45#endif /* HAVE_UNISTD_H */
46#include <pwd.h>
47#include <siad.h>
48
49#include "sudo.h"
50#include "sudo_auth.h"
51
52static int sudo_collect	__P((int, int, uchar_t *, int, prompt_t *));
53
54static char *def_prompt;
55
56/*
57 * Collection routine (callback) for limiting the timeouts in SIA
58 * prompts and (possibly) setting a custom prompt.
59 */
60static int
61sudo_collect(timeout, rendition, title, nprompts, prompts)
62    int timeout;
63    int rendition;
64    uchar_t *title;
65    int nprompts;
66    prompt_t *prompts;
67{
68    switch (rendition) {
69	case SIAFORM:
70	case SIAONELINER:
71	    if (timeout <= 0 || timeout > def_passwd_timeout * 60)
72		timeout = def_passwd_timeout * 60;
73	    /*
74	     * Substitute custom prompt if a) the sudo prompt is not "Password:"
75	     * and b) the SIA prompt is "Password:" (so we know it is safe).
76	     * This keeps us from overwriting things like S/Key challenges.
77	     */
78	    if (strcmp((char *)prompts[0].prompt, "Password:") == 0 &&
79		strcmp(def_prompt, "Password:") != 0)
80		prompts[0].prompt = (unsigned char *)def_prompt;
81	    break;
82	default:
83	    break;
84    }
85
86    return sia_collect_trm(timeout, rendition, title, nprompts, prompts);
87}
88
89int
90sia_setup(pw, promptp, auth)
91    struct passwd *pw;
92    char **promptp;
93    sudo_auth *auth;
94{
95    SIAENTITY *siah = NULL;
96    extern int Argc;
97    extern char **Argv;
98
99    if (sia_ses_init(&siah, Argc, Argv, NULL, pw->pw_name, ttyname(0), 1, NULL)
100	!= SIASUCCESS) {
101
102	log_error(USE_ERRNO|NO_MAIL,
103	    "unable to initialize SIA session");
104	return AUTH_FATAL;
105    }
106
107    auth->data = (void *) siah;
108    return AUTH_SUCCESS;
109}
110
111int
112sia_verify(pw, prompt, auth)
113    struct passwd *pw;
114    char *prompt;
115    sudo_auth *auth;
116{
117    SIAENTITY *siah = (SIAENTITY *) auth->data;
118
119    def_prompt = prompt;		/* for sudo_collect */
120
121    /* XXX - need a way to detect user hitting return or EOF at prompt */
122    if (sia_ses_reauthent(sudo_collect, siah) == SIASUCCESS)
123	return AUTH_SUCCESS;
124    else
125	return AUTH_FAILURE;
126}
127
128int
129sia_cleanup(pw, auth)
130    struct passwd *pw;
131    sudo_auth *auth;
132{
133    SIAENTITY *siah = (SIAENTITY *) auth->data;
134
135    (void) sia_ses_release(&siah);
136    return AUTH_SUCCESS;
137}
138