1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
|
/* $OpenBSD: auth.h,v 1.41 2002/09/26 11:38:43 markus Exp $ */
#ifndef _AUTH_H
#define _AUTH_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include "key.h"
#include "hostfile.h"
#include <openssl/rsa.h>
#ifdef USE_PAM
#include <security/pam_appl.h>
#endif /* USE_PAM */
#ifdef HAVE_LOGIN_CAP
#include <login_cap.h>
#endif
#ifdef BSD_AUTH
#include <bsd_auth.h>
#endif
#ifdef KRB5
#include <krb5.h>
#endif
typedef struct Authctxt Authctxt;
typedef struct Authmethod Authmethod;
typedef struct KbdintDevice KbdintDevice;
#ifdef USE_PAM
typedef struct pam_stuff pam_stuff;
struct pam_stuff {
Authctxt *authctxt;
pam_handle_t *h;
int state;
int last_pam_retval;
};
/* See auth-pam.h and auth-pam.c */
#define PAM_S_DONE_ACCT_MGMT 0x01 /* acct_mgmt done */
#define PAM_S_DONE_SETCRED 0x02 /* setcred done */
#define PAM_S_DONE_OPEN_SESSION 0x04 /* open_session done */
#define PAM_S_DONE 0x07 /* all done */
#endif /* USE_PAM */
struct Authctxt {
int success;
int valid;
int attempt; /* all userauth attempt count */
int init_attempt; /* passwd/kbd-int attempt count */
int failures;
int init_failures;
int unwind_dispatch_loop;
int v1_auth_type;
char *v1_auth_name;
Authmethod *method;
char *user;
char *service;
struct passwd *pw;
char *style;
void *kbdintctxt; /* XXX Switch to method_data;
v1 still needs this*/
#ifdef USE_PAM
pam_stuff *pam;
char *cuser; /* client side user, needed for setting
PAM_AUSER for hostbased authentication
using roles */
u_long last_login_time; /* need to get the time of
last login before calling
pam_open_session() */
char last_login_host[MAXHOSTNAMELEN];
int pam_retval; /* pam_stuff is cleaned before
BSM login failure auditing */
#endif /* USE_PAM */
/* SUNW - What follows remains to reduce diffs with OpenSSH but
* is not used in Solaris. The Solaris SSH internal
* architecture requires that this stuff move into the
* Authmethod method_data.
*/
#ifndef SUNW_SSH
#ifdef BSD_AUTH
auth_session_t *as;
#endif
#ifdef KRB4
char *krb4_ticket_file;
#endif
#ifdef KRB5
krb5_context krb5_ctx;
krb5_auth_context krb5_auth_ctx;
krb5_ccache krb5_fwd_ccache;
krb5_principal krb5_user;
char *krb5_ticket_file;
#endif
void *methoddata;
#endif /* SUNW_SSH */
};
struct Authmethod {
char *name;
int *enabled;
/*
* Userauth method state tracking fields updated in
* input_userauth_request() and auth-pam.c.
*
* The "void (*userauth)(Authctxt *authctxt)" function
* communicates the userauth result (success, failure,
* "postponed," abandoned) through the 'authenticated',
* 'postponed' and 'abandoned' fields. Partial success is
* indicated by requiring other userauths to be used by setting
* their 'required' or 'sufficient' fields.
*
* Individual methods should only ever set 'not_again' if it
* makes no sense to complete the same userauth more than once,
* and they should set any methods' sufficient or required flags
* in order to force partial authentication and require that
* more userauths be tried. The (void *) 'method_data' and
* 'hist_method_data' pointers can be used by methods such as
* pubkey which may make sense to run more than once during
* userauth or which may require multiple round tripes (e.g.,
* keyboard-interactive) and which need to keep some state;
* 'hist_method_data' is there specifically for pubkey userauth
* where multiple successful attempts should all use different
* keys.
*
* The "attempts," "abandons," "successes" and "failures" fields
* count the number of times a method has been attempted,
* abandoned, and has succeeded or failed. Note that pubkey
* userauth does not double-count sig-less probes that are
* followed by a pubkey request for the same pubkey anw with a
* signature.
*/
void (*userauth)(Authctxt *authctxt);
void (*abandon)(Authctxt *, Authmethod *);
void *method_data;
void *hist_method_data;
unsigned int is_initial;
unsigned int attempts:8;
unsigned int abandons:8;
unsigned int successes:8;
unsigned int failures:8;
/*
* Post-attempt state booleans (authenticated, abandoned, etc...)
*/
unsigned int authenticated:1;
unsigned int not_again:1;
unsigned int sufficient:1;
unsigned int required:1;
unsigned int postponed:1;
unsigned int abandoned:1;
/*
* NOTE: multi-round-trip userauth methods can either
* recursively call dispatch_run and detect abandonment
* within their message handlers (as PAM kbd-int does) or
* set the postponed flag and let input_userauth_request()
* detect abandonment (i.e., initiation of some userauth
* method before completion of a started, multi-round-trip
* userauth method).
*
*/
};
/*
* Keyboard interactive device:
* init_ctx returns: non NULL upon success
* query returns: 0 - success, otherwise failure
* respond returns: 0 - success, 1 - need further interaction,
* otherwise - failure
*/
struct KbdintDevice
{
const char *name;
void* (*init_ctx)(Authctxt*);
int (*query)(void *ctx, char **name, char **infotxt,
u_int *numprompts, char ***prompts, u_int **echo_on);
int (*respond)(void *ctx, u_int numresp, char **responses);
void (*free_ctx)(void *ctx);
};
int auth_rhosts(struct passwd *, const char *);
int
auth_rhosts2(struct passwd *, const char *, const char *, const char *);
int auth_rhosts_rsa(struct passwd *, char *, Key *);
int auth_password(Authctxt *, const char *);
int auth_rsa(struct passwd *, BIGNUM *);
int auth_rsa_challenge_dialog(Key *);
BIGNUM *auth_rsa_generate_challenge(Key *);
int auth_rsa_verify_response(Key *, BIGNUM *, u_char[]);
int auth_rsa_key_allowed(struct passwd *, BIGNUM *, Key **);
int auth_rhosts_rsa_key_allowed(struct passwd *, char *, char *, Key *);
int hostbased_key_allowed(struct passwd *, const char *, char *, Key *);
int user_key_allowed(struct passwd *, Key *);
#ifdef KRB4
#include <krb.h>
int auth_krb4(Authctxt *, KTEXT, char **, KTEXT);
int auth_krb4_password(Authctxt *, const char *);
void krb4_cleanup_proc(void *);
#ifdef AFS
#include <kafs.h>
int auth_krb4_tgt(Authctxt *, const char *);
int auth_afs_token(Authctxt *, const char *);
#endif /* AFS */
#endif /* KRB4 */
#ifdef KRB5
int auth_krb5(Authctxt *authctxt, krb5_data *auth, char **client, krb5_data *);
int auth_krb5_tgt(Authctxt *authctxt, krb5_data *tgt);
int auth_krb5_password(Authctxt *authctxt, const char *password);
void krb5_cleanup_proc(void *authctxt);
#endif /* KRB5 */
#include "auth-pam.h"
#include "auth2-pam.h"
Authctxt *do_authentication(void);
Authctxt *do_authentication2(void);
#ifdef HAVE_BSM
void audit_failed_login_cleanup(void *);
#endif /* HAVE_BSM */
int userauth_check_partial_failure(Authctxt *authctxt);
void userauth_force_kbdint(void);
Authctxt *authctxt_new(void);
void auth_log(Authctxt *, int, char *, char *);
void userauth_finish(Authctxt *, char *);
void userauth_user_svc_change(Authctxt *authctxt,
char *user,
char *service);
int auth_root_allowed(char *);
char *auth2_read_banner(void);
void privsep_challenge_enable(void);
void auth2_challenge(Authctxt *, char *);
void auth2_challenge_abandon(Authctxt *);
int bsdauth_query(void *, char **, char **, u_int *, char ***, u_int **);
int bsdauth_respond(void *, u_int, char **);
int skey_query(void *, char **, char **, u_int *, char ***, u_int **);
int skey_respond(void *, u_int, char **);
struct passwd * getpwnamallow(const char *user);
int run_auth_hook(const char *, const char *, const char *);
char *get_challenge(Authctxt *);
int verify_response(Authctxt *, const char *);
struct passwd * auth_get_user(void);
char *authorized_keys_file(struct passwd *);
char *authorized_keys_file2(struct passwd *);
int
secure_filename(FILE *, const char *, struct passwd *, char *, size_t);
HostStatus
check_key_in_hostfiles(struct passwd *, Key *, const char *,
const char *, const char *);
/* hostkey handling */
#ifndef lint
Key *get_hostkey_by_index(int);
Key *get_hostkey_by_type(int);
int get_hostkey_index(Key *);
#endif /* lint */
int ssh1_session_key(BIGNUM *);
/* debug messages during authentication */
void auth_debug_add(const char *fmt,...) __attribute__((format(printf, 1, 2)));
void auth_debug_send(void);
void auth_debug_reset(void);
#define AUTH_FAIL_MAX 6
#define AUTH_FAIL_LOG (AUTH_FAIL_MAX/2)
#define AUTH_FAIL_MSG "Too many authentication failures for %.100s"
#define SKEY_PROMPT "\nS/Key Password: "
#ifdef __cplusplus
}
#endif
#endif /* _AUTH_H */
|