Annotation of embedaddon/sudo/plugins/sudoers/auth/bsdauth.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (c) 2000-2005, 2007-2008, 2010-2011
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: *
17: * Sponsored in part by the Defense Advanced Research Projects
18: * Agency (DARPA) and Air Force Research Laboratory, Air Force
19: * Materiel Command, USAF, under agreement number F39502-99-1-0512.
20: */
21:
22: #include <config.h>
23:
24: #include <sys/types.h>
25: #include <sys/param.h>
26: #include <stdio.h>
27: #ifdef STDC_HEADERS
28: # include <stdlib.h>
29: # include <stddef.h>
30: #else
31: # ifdef HAVE_STDLIB_H
32: # include <stdlib.h>
33: # endif
34: #endif /* STDC_HEADERS */
35: #ifdef HAVE_STRING_H
36: # include <string.h>
37: #endif /* HAVE_STRING_H */
38: #ifdef HAVE_STRINGS_H
39: # include <strings.h>
40: #endif /* HAVE_STRING_H */
41: #ifdef HAVE_UNISTD_H
42: # include <unistd.h>
43: #endif /* HAVE_UNISTD_H */
44: #include <ctype.h>
45: #include <pwd.h>
46: #include <signal.h>
47:
48: #include <login_cap.h>
49: #include <bsd_auth.h>
50:
51: #include "sudoers.h"
52: #include "sudo_auth.h"
53:
54: extern char *login_style; /* from sudo.c */
55:
56: int
57: bsdauth_init(struct passwd *pw, sudo_auth *auth)
58: {
59: static auth_session_t *as;
60: extern login_cap_t *lc; /* from sudo.c */
61:
62: if ((as = auth_open()) == NULL) {
63: log_error(USE_ERRNO|NO_EXIT|NO_MAIL,
64: _("unable to begin bsd authentication"));
65: return AUTH_FATAL;
66: }
67:
68: /* XXX - maybe sanity check the auth style earlier? */
69: login_style = login_getstyle(lc, login_style, "auth-sudo");
70: if (login_style == NULL) {
71: log_error(NO_EXIT|NO_MAIL, _("invalid authentication type"));
72: auth_close(as);
73: return AUTH_FATAL;
74: }
75:
76: if (auth_setitem(as, AUTHV_STYLE, login_style) < 0 ||
77: auth_setitem(as, AUTHV_NAME, pw->pw_name) < 0 ||
78: auth_setitem(as, AUTHV_CLASS, login_class) < 0) {
79: log_error(NO_EXIT|NO_MAIL, _("unable to setup authentication"));
80: auth_close(as);
81: return AUTH_FATAL;
82: }
83:
84: auth->data = (void *) as;
85: return AUTH_SUCCESS;
86: }
87:
88: int
89: bsdauth_verify(struct passwd *pw, char *prompt, sudo_auth *auth)
90: {
91: char *pass;
92: char *s;
93: size_t len;
94: int authok = 0;
95: sigaction_t sa, osa;
96: auth_session_t *as = (auth_session_t *) auth->data;
97:
98: /* save old signal handler */
99: sigemptyset(&sa.sa_mask);
100: sa.sa_flags = SA_RESTART;
101: sa.sa_handler = SIG_DFL;
102: (void) sigaction(SIGCHLD, &sa, &osa);
103:
104: /*
105: * If there is a challenge then print that instead of the normal
106: * prompt. If the user just hits return we prompt again with echo
107: * turned on, which is useful for challenge/response things like
108: * S/Key.
109: */
110: if ((s = auth_challenge(as)) == NULL) {
111: pass = auth_getpass(prompt, def_passwd_timeout * 60, SUDO_CONV_PROMPT_ECHO_OFF);
112: } else {
113: pass = auth_getpass(prompt, def_passwd_timeout * 60, SUDO_CONV_PROMPT_ECHO_OFF);
114: if (pass && *pass == '\0') {
115: if ((prompt = strrchr(s, '\n')))
116: prompt++;
117: else
118: prompt = s;
119:
120: /*
121: * Append '[echo on]' to the last line of the challenge and
122: * reprompt with echo turned on.
123: */
124: len = strlen(prompt) - 1;
125: while (isspace(prompt[len]) || prompt[len] == ':')
126: prompt[len--] = '\0';
127: easprintf(&s, "%s [echo on]: ", prompt);
128: pass = auth_getpass(prompt, def_passwd_timeout * 60,
129: SUDO_CONV_PROMPT_ECHO_ON);
130: free(s);
131: }
132: }
133:
134: if (pass) {
135: authok = auth_userresponse(as, pass, 1);
136: zero_bytes(pass, strlen(pass));
137: }
138:
139: /* restore old signal handler */
140: (void) sigaction(SIGCHLD, &osa, NULL);
141:
142: if (authok)
143: return AUTH_SUCCESS;
144:
145: if (!pass)
146: return AUTH_INTR;
147:
148: if ((s = auth_getvalue(as, "errormsg")) != NULL)
149: log_error(NO_EXIT|NO_MAIL, "%s", s);
150: return AUTH_FAILURE;
151: }
152:
153: int
154: bsdauth_cleanup(struct passwd *pw, sudo_auth *auth)
155: {
156: auth_session_t *as = (auth_session_t *) auth->data;
157:
158: auth_close(as);
159:
160: return AUTH_SUCCESS;
161: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>