2 * Copyright (c) 1999-2005 Todd C. Miller <Todd.Miller@courtesan.com>
3 * Copyright (c) 2002 Michael Stroucken <michael@stroucken.org>
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.
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 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
17 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
18 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20 * Sponsored in part by the Defense Advanced Research Projects
21 * Agency (DARPA) and Air Force Research Laboratory, Air Force
22 * Materiel Command, USAF, under agreement number F39502-99-1-0512.
27 #include <sys/types.h>
28 #include <sys/param.h>
37 #endif /* STDC_HEADERS */
41 # ifdef HAVE_STRINGS_H
44 #endif /* HAVE_STRING_H */
47 #endif /* HAVE_UNISTD_H */
51 # include "emul/err.h"
52 #endif /* HAVE_ERR_H */
55 /* Needed for SecurID v5.0 Authentication on UNIX */
61 #include "sudo_auth.h"
64 __unused static const char rcsid[] = "$Sudo: securid5.c,v 1.6.2.2 2007/06/12 00:56:44 millert Exp $";
68 * securid_init - Initialises communications with ACE server
72 * auth - sudo authentication structure
75 * auth - auth->data contains pointer to new SecurID handle
76 * return code - Fatal if initialization unsuccessful, otherwise
80 securid_init(pw, promptp, auth)
85 static SDI_HANDLE sd_dat; /* SecurID handle */
87 auth->data = (VOID *) &sd_dat; /* For method-specific data */
89 /* Start communications */
90 if (AceInitialize() != SD_FALSE)
93 warnx("failed to initialise the ACE API library");
98 * securid_setup - Initialises a SecurID transaction and locks out other
102 * pw - struct passwd for username
104 * auth - sudo authentication structure for SecurID handle
107 * return code - Success if transaction started correctly, fatal
111 securid_setup(pw, promptp, auth)
116 SDI_HANDLE *sd = (SDI_HANDLE *) auth->data;
119 /* Re-initialize SecurID every time. */
120 if (SD_Init(sd) != ACM_OK) {
121 warnx("unable to contact the SecurID server");
125 /* Lock new PIN code */
126 retval = SD_Lock(*sd, pw->pw_name);
130 warnx("User ID locked for SecurID Authentication");
131 return(AUTH_SUCCESS);
133 case ACE_UNDEFINED_USERNAME:
134 warnx("invalid username length for SecurID");
137 case ACE_ERR_INVALID_HANDLE:
138 warnx("invalid Authentication Handle for SecurID");
141 case ACM_ACCESS_DENIED:
142 warnx("SecurID communication failed");
146 warnx("unknown SecurID error");
152 * securid_verify - Authenticates user and handles ACE responses
155 * pw - struct passwd for username
157 * auth - sudo authentication structure for SecurID handle
160 * return code - Success on successful authentication, failure on
161 * incorrect authentication, fatal on errors
164 securid_verify(pw, pass, auth)
169 SDI_HANDLE *sd = (SDI_HANDLE *) auth->data;
172 pass = (char *) tgetpass("Enter your PASSCODE: ",
173 def_passwd_timeout * 60, tgetpass_flags);
175 /* Have ACE verify password */
176 switch (SD_Check(*sd, pass, pw->pw_name)) {
181 case ACE_UNDEFINED_PASSCODE:
182 warnx("invalid passcode length for SecurID");
186 case ACE_UNDEFINED_USERNAME:
187 warnx("invalid username length for SecurID");
191 case ACE_ERR_INVALID_HANDLE:
192 warnx("invalid Authentication Handle for SecurID");
196 case ACM_ACCESS_DENIED:
200 case ACM_NEXT_CODE_REQUIRED:
201 /* Sometimes (when current token close to expire?)
202 ACE challenges for the next token displayed
203 (entered without the PIN) */
204 pass = (char *) tgetpass("\
206 Wait for the token code to change, \n\
207 then enter the new token code.\n", \
208 def_passwd_timeout * 60, tgetpass_flags);
210 if (SD_Next(*sd, pass) == ACM_OK) {
218 case ACM_NEW_PIN_REQUIRED:
220 * This user's SecurID has not been activated yet,
221 * or the pin has been reset
223 /* XXX - Is setting up a new PIN within sudo's scope? */
225 fprintf(stderr, "Your SecurID access has not yet been set up.\n");
226 fprintf(stderr, "Please set up a PIN before you try to authenticate.\n");
231 warnx("unknown SecurID error");
239 /* Return stored state to calling process */