2 * Copyright (c) 1994-1996, 1998-1999, 2001
3 * Todd C. Miller <Todd.Miller@courtesan.com>. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * 3. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
19 * 4. Products derived from this software may not be called "Sudo" nor
20 * may "Sudo" appear in their names without specific prior written
21 * permission from the author.
23 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
24 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
25 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
26 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
29 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
30 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
31 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
32 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 #include <sys/types.h>
38 #include <sys/param.h>
47 #endif /* STDC_HEADERS */
51 # ifdef HAVE_STRINGS_H
54 #endif /* HAVE_STRING_H */
57 #endif /* HAVE_UNISTD_H */
60 #if defined(HAVE_SKEY)
63 #define rfc1938challenge skeychallenge
64 #define rfc1938verify skeyverify
65 #elif defined(HAVE_OPIE)
68 #define rfc1938challenge opiechallenge
69 #define rfc1938verify opieverify
73 #include "sudo_auth.h"
76 static const char rcsid[] = "$Sudo: rfc1938.c,v 1.9 2001/12/14 19:52:53 millert Exp $";
80 rfc1938_setup(pw, promptp, auth)
86 static char *orig_prompt = NULL, *new_prompt = NULL;
87 static int op_len, np_size;
88 static struct RFC1938 rfc1938;
90 /* Stash a pointer to the rfc1938 struct if we have not initialized */
92 auth->data = &rfc1938;
94 /* Save the original prompt */
95 if (orig_prompt == NULL) {
96 orig_prompt = *promptp;
97 op_len = strlen(orig_prompt);
99 /* Ignore trailing colon (we will add our own) */
100 if (orig_prompt[op_len - 1] == ':')
102 else if (op_len >= 2 && orig_prompt[op_len - 1] == ' '
103 && orig_prompt[op_len - 2] == ':')
108 /* Close old stream */
110 (void) fclose(rfc1938.keyfile);
114 * Look up the user and get the rfc1938 challenge.
115 * If the user is not in the OTP db, only post a fatal error if
116 * we are running alone (since they may just use a normal passwd).
118 if (rfc1938challenge(&rfc1938, pw->pw_name, challenge) != 0) {
119 if (IS_ONEANDONLY(auth)) {
120 (void) fprintf(stderr,
121 "%s: You do not exist in the %s database.\n",
122 Argv[0], auth->name);
125 return(AUTH_FAILURE);
129 /* Get space for new prompt with embedded challenge */
130 if (np_size < op_len + strlen(challenge) + 7) {
131 np_size = op_len + strlen(challenge) + 7;
132 new_prompt = (char *) erealloc(new_prompt, np_size);
135 if (def_flag(I_LONG_OTP_PROMPT))
136 (void) sprintf(new_prompt, "%s\n%s", challenge, orig_prompt);
138 (void) sprintf(new_prompt, "%.*s [ %s ]:", op_len, orig_prompt,
141 *promptp = new_prompt;
142 return(AUTH_SUCCESS);
146 rfc1938_verify(pw, pass, auth)
152 if (rfc1938verify((struct RFC1938 *) auth->data, pass) == 0)
153 return(AUTH_SUCCESS);
155 return(AUTH_FAILURE);