Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sudo-project
GitHub Repository: sudo-project/sudo
Path: blob/main/plugins/sudoers/auth/rfc1938.c
1532 views
1
/*
2
* SPDX-License-Identifier: ISC
3
*
4
* Copyright (c) 1994-1996, 1998-2005, 2010-2012, 2014-2015
5
* Todd C. Miller <[email protected]>
6
*
7
* Permission to use, copy, modify, and distribute this software for any
8
* purpose with or without fee is hereby granted, provided that the above
9
* copyright notice and this permission notice appear in all copies.
10
*
11
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
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
#if defined(HAVE_SKEY) || defined(HAVE_OPIE)
27
28
#include <sys/types.h>
29
#include <stdio.h>
30
#include <stdlib.h>
31
#include <string.h>
32
#include <unistd.h>
33
#include <pwd.h>
34
35
#if defined(HAVE_SKEY)
36
# include <skey.h>
37
# define RFC1938 skey
38
# ifdef HAVE_RFC1938_SKEYCHALLENGE
39
# define rfc1938challenge(a,b,c,d) skeychallenge((a),(b),(c),(d))
40
# else
41
# define rfc1938challenge(a,b,c,d) skeychallenge((a),(b),(c))
42
# endif
43
# define rfc1938verify(a,b) skeyverify((a),(b))
44
#elif defined(HAVE_OPIE)
45
# include <opie.h>
46
# define RFC1938 opie
47
# define rfc1938challenge(a,b,c,d) opiechallenge((a),(b),(c))
48
# define rfc1938verify(a,b) opieverify((a),(b))
49
#endif
50
51
#include <sudoers.h>
52
#include "sudo_auth.h"
53
54
int
55
sudo_rfc1938_setup(const struct sudoers_context *ctx, struct passwd *pw,
56
char **promptp, sudo_auth *auth)
57
{
58
char challenge[256];
59
size_t challenge_len;
60
static char *orig_prompt = NULL, *new_prompt = NULL;
61
static size_t op_len, np_size;
62
static struct RFC1938 rfc1938;
63
debug_decl(sudo_rfc1938_setup, SUDOERS_DEBUG_AUTH);
64
65
/* Stash a pointer to the rfc1938 struct if we have not initialized */
66
if (!auth->data)
67
auth->data = &rfc1938;
68
69
/* Save the original prompt */
70
if (orig_prompt == NULL) {
71
orig_prompt = *promptp;
72
op_len = strlen(orig_prompt);
73
74
/* Ignore trailing colon (we will add our own) */
75
if (orig_prompt[op_len - 1] == ':')
76
op_len--;
77
else if (op_len >= 2 && orig_prompt[op_len - 1] == ' '
78
&& orig_prompt[op_len - 2] == ':')
79
op_len -= 2;
80
}
81
82
#ifdef HAVE_SKEY
83
/* Close old stream */
84
if (rfc1938.keyfile)
85
(void) fclose(rfc1938.keyfile);
86
#endif
87
88
/*
89
* Look up the user and get the rfc1938 challenge.
90
* If the user is not in the OTP db, only post a fatal error if
91
* we are running alone (since they may just use a normal passwd).
92
*/
93
if (rfc1938challenge(&rfc1938, pw->pw_name, challenge, sizeof(challenge))) {
94
if (IS_ONEANDONLY(auth)) {
95
sudo_warnx(U_("you do not exist in the %s database"), auth->name);
96
debug_return_int(AUTH_ERROR);
97
} else {
98
debug_return_int(AUTH_FAILURE);
99
}
100
}
101
102
/* Get space for new prompt with embedded challenge */
103
challenge_len = strlen(challenge);
104
if (np_size < op_len + challenge_len + 7) {
105
char *p = realloc(new_prompt, op_len + challenge_len + 7);
106
if (p == NULL) {
107
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
108
debug_return_int(AUTH_ERROR);
109
}
110
np_size = op_len + challenge_len + 7;
111
new_prompt = p;
112
}
113
114
if (def_long_otp_prompt)
115
(void) snprintf(new_prompt, np_size, "%s\n%s", challenge, orig_prompt);
116
else
117
(void) snprintf(new_prompt, np_size, "%.*s [ %s ]:", (int)op_len,
118
orig_prompt, challenge);
119
120
*promptp = new_prompt;
121
debug_return_int(AUTH_SUCCESS);
122
}
123
124
int
125
sudo_rfc1938_verify(const struct sudoers_context *ctx, struct passwd *pw,
126
const char *pass, sudo_auth *auth, struct sudo_conv_callback *callback)
127
{
128
debug_decl(sudo_rfc1938_verify, SUDOERS_DEBUG_AUTH);
129
130
if (rfc1938verify((struct RFC1938 *) auth->data, (char *)pass) == 0)
131
debug_return_int(AUTH_SUCCESS);
132
else
133
debug_return_int(AUTH_FAILURE);
134
}
135
136
#endif /* HAVE_SKEY || HAVE_OPIE */
137
138