View | Details | Raw Unified | Return to bug 2408 | Differences between
and this patch

Collapse All | Expand All

(-)a/auth-pam.c (+4 lines)
Lines 689-694 sshpam_init_ctx(Authctxt *authctxt) Link Here
689
		return (NULL);
689
		return (NULL);
690
	}
690
	}
691
691
692
	/* Notify PAM about any already successful auth methods */
693
	if (authctxt->auth_details)
694
		do_pam_putenv("SSH_USER_AUTH", authctxt->auth_details);
695
692
	ctxt = xcalloc(1, sizeof *ctxt);
696
	ctxt = xcalloc(1, sizeof *ctxt);
693
697
694
	/* Start the authentication thread */
698
	/* Start the authentication thread */
(-)a/auth.h (+3 lines)
Lines 81-86 struct Authctxt { Link Here
81
81
82
	struct sshkey	**prev_userkeys;
82
	struct sshkey	**prev_userkeys;
83
	u_int		 nprev_userkeys;
83
	u_int		 nprev_userkeys;
84
85
	char		*last_details;
86
	char		*auth_details;
84
};
87
};
85
/*
88
/*
86
 * Every authentication method has to handle authentication requests for
89
 * Every authentication method has to handle authentication requests for
(-)a/auth2-hostbased.c (-4 / +10 lines)
Lines 60-66 userauth_hostbased(Authctxt *authctxt) Link Here
60
{
60
{
61
	Buffer b;
61
	Buffer b;
62
	Key *key = NULL;
62
	Key *key = NULL;
63
	char *pkalg, *cuser, *chost, *service;
63
	char *pkalg, *cuser, *chost, *service, *pubkey;
64
	u_char *pkblob, *sig;
64
	u_char *pkblob, *sig;
65
	u_int alen, blen, slen;
65
	u_int alen, blen, slen;
66
	int pktype;
66
	int pktype;
Lines 132-146 userauth_hostbased(Authctxt *authctxt) Link Here
132
	buffer_dump(&b);
132
	buffer_dump(&b);
133
#endif
133
#endif
134
134
135
	pubkey_auth_info(authctxt, key,
135
	pubkey = sshkey_format_oneline(key, options.fingerprint_hash);
136
	    "client user \"%.100s\", client host \"%.100s\"", cuser, chost);
136
	auth_info(authctxt,
137
	    "%s, client user \"%.100s\", client host \"%.100s\"",
138
	    pubkey, cuser, chost);
137
139
138
	/* test for allowed key and correct signature */
140
	/* test for allowed key and correct signature */
139
	authenticated = 0;
141
	authenticated = 0;
140
	if (PRIVSEP(hostbased_key_allowed(authctxt->pw, cuser, chost, key)) &&
142
	if (PRIVSEP(hostbased_key_allowed(authctxt->pw, cuser, chost, key)) &&
141
	    PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b),
143
	    PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b),
142
			buffer_len(&b))) == 1)
144
			buffer_len(&b))) == 1) {
143
		authenticated = 1;
145
		authenticated = 1;
146
		authctxt->last_details = pubkey;
147
	} else {
148
		free(pubkey);
149
	}
144
150
145
	buffer_free(&b);
151
	buffer_free(&b);
146
done:
152
done:
(-)a/auth2-pubkey.c (-22 / +12 lines)
Lines 79-85 userauth_pubkey(Authctxt *authctxt) Link Here
79
{
79
{
80
	Buffer b;
80
	Buffer b;
81
	Key *key = NULL;
81
	Key *key = NULL;
82
	char *pkalg, *userstyle, *fp = NULL;
82
	char *pkalg, *userstyle, *pubkey, *fp = NULL;
83
	u_char *pkblob, *sig;
83
	u_char *pkblob, *sig;
84
	u_int alen, blen, slen;
84
	u_int alen, blen, slen;
85
	int have_sig, pktype;
85
	int have_sig, pktype;
Lines 171-177 userauth_pubkey(Authctxt *authctxt) Link Here
171
#ifdef DEBUG_PK
171
#ifdef DEBUG_PK
172
		buffer_dump(&b);
172
		buffer_dump(&b);
173
#endif
173
#endif
174
		pubkey_auth_info(authctxt, key, NULL);
174
		pubkey = sshkey_format_oneline(key, options.fingerprint_hash);
175
		auth_info(authctxt, "%s", pubkey);
175
176
176
		/* test for correct signature */
177
		/* test for correct signature */
177
		authenticated = 0;
178
		authenticated = 0;
Lines 179-187 userauth_pubkey(Authctxt *authctxt) Link Here
179
		    PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b),
180
		    PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b),
180
		    buffer_len(&b))) == 1) {
181
		    buffer_len(&b))) == 1) {
181
			authenticated = 1;
182
			authenticated = 1;
183
			authctxt->last_details = pubkey;
182
			/* Record the successful key to prevent reuse */
184
			/* Record the successful key to prevent reuse */
183
			auth2_record_userkey(authctxt, key);
185
			auth2_record_userkey(authctxt, key);
184
			key = NULL; /* Don't free below */
186
			key = NULL; /* Don't free below */
187
		} else {
188
			free(pubkey);
185
		}
189
		}
186
		buffer_free(&b);
190
		buffer_free(&b);
187
		free(sig);
191
		free(sig);
Lines 222-228 done: Link Here
222
void
226
void
223
pubkey_auth_info(Authctxt *authctxt, const Key *key, const char *fmt, ...)
227
pubkey_auth_info(Authctxt *authctxt, const Key *key, const char *fmt, ...)
224
{
228
{
225
	char *fp, *extra;
229
	char *extra, *pubkey;
226
	va_list ap;
230
	va_list ap;
227
	int i;
231
	int i;
228
232
Lines 232-258 pubkey_auth_info(Authctxt *authctxt, const Key *key, const char *fmt, ...) Link Here
232
		i = vasprintf(&extra, fmt, ap);
236
		i = vasprintf(&extra, fmt, ap);
233
		va_end(ap);
237
		va_end(ap);
234
		if (i < 0 || extra == NULL)
238
		if (i < 0 || extra == NULL)
235
			fatal("%s: vasprintf failed", __func__);	
239
			fatal("%s: vasprintf failed", __func__);
236
	}
240
	}
237
241
238
	if (key_is_cert(key)) {
242
	pubkey = sshkey_format_oneline(key, options.fingerprint_hash);
239
		fp = sshkey_fingerprint(key->cert->signature_key,
243
	auth_info(authctxt, "%s%s%s", pubkey, extra == NULL ? "" : ", ",
240
		    options.fingerprint_hash, SSH_FP_DEFAULT);
244
	    extra == NULL ? "" : extra);
241
		auth_info(authctxt, "%s ID %s (serial %llu) CA %s %s%s%s", 
245
	free(pubkey);
242
		    key_type(key), key->cert->key_id,
243
		    (unsigned long long)key->cert->serial,
244
		    key_type(key->cert->signature_key),
245
		    fp == NULL ? "(null)" : fp,
246
		    extra == NULL ? "" : ", ", extra == NULL ? "" : extra);
247
		free(fp);
248
	} else {
249
		fp = sshkey_fingerprint(key, options.fingerprint_hash,
250
		    SSH_FP_DEFAULT);
251
		auth_info(authctxt, "%s %s%s%s", key_type(key),
252
		    fp == NULL ? "(null)" : fp,
253
		    extra == NULL ? "" : ", ", extra == NULL ? "" : extra);
254
		free(fp);
255
	}
256
	free(extra);
246
	free(extra);
257
}
247
}
258
248
(-)a/auth2.c (+13 lines)
Lines 293-298 userauth_finish(Authctxt *authctxt, int authenticated, const char *method, Link Here
293
    const char *submethod)
293
    const char *submethod)
294
{
294
{
295
	char *methods;
295
	char *methods;
296
	char *prev_auth_details;
296
	int partial = 0;
297
	int partial = 0;
297
298
298
	if (!authctxt->valid && authenticated)
299
	if (!authctxt->valid && authenticated)
Lines 323-328 userauth_finish(Authctxt *authctxt, int authenticated, const char *method, Link Here
323
	if (authctxt->postponed)
324
	if (authctxt->postponed)
324
		return;
325
		return;
325
326
327
	if (authenticated || partial) {
328
		prev_auth_details = authctxt->auth_details;
329
		xasprintf(&authctxt->auth_details, "%s%s%s%s%s",
330
		    prev_auth_details ? prev_auth_details : "",
331
		    prev_auth_details ? ", " : "", method,
332
		    authctxt->last_details ? ": " : "",
333
		    authctxt->last_details ? authctxt->last_details : "");
334
		free(authctxt->last_details);
335
		authctxt->last_details = NULL;
336
		free(prev_auth_details);
337
	}
338
326
#ifdef USE_PAM
339
#ifdef USE_PAM
327
	if (options.use_pam && authenticated) {
340
	if (options.use_pam && authenticated) {
328
		if (!PRIVSEP(do_pam_account())) {
341
		if (!PRIVSEP(do_pam_account())) {
(-)a/monitor.c (+17 lines)
Lines 334-339 monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) Link Here
334
{
334
{
335
	struct mon_table *ent;
335
	struct mon_table *ent;
336
	int authenticated = 0, partial = 0;
336
	int authenticated = 0, partial = 0;
337
	char *prev_auth_details;
337
338
338
	debug3("preauth child monitor started");
339
	debug3("preauth child monitor started");
339
340
Lines 365-370 monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) Link Here
365
		auth_submethod = NULL;
366
		auth_submethod = NULL;
366
		authenticated = (monitor_read(pmonitor, mon_dispatch, &ent) == 1);
367
		authenticated = (monitor_read(pmonitor, mon_dispatch, &ent) == 1);
367
368
369
		if (authenticated) {
370
			prev_auth_details = authctxt->auth_details;
371
			xasprintf(&authctxt->auth_details, "%s%s%s%s%s",
372
			    prev_auth_details ? prev_auth_details : "",
373
			    prev_auth_details ? ", " : "", auth_method,
374
			    authctxt->last_details ? ": " : "",
375
			    authctxt->last_details ? authctxt->last_details : "");
376
			free(authctxt->last_details);
377
			authctxt->last_details = NULL;
378
			free(prev_auth_details);
379
		}
380
368
		/* Special handling for multiple required authentications */
381
		/* Special handling for multiple required authentications */
369
		if (options.num_auth_methods != 0) {
382
		if (options.num_auth_methods != 0) {
370
			if (!compat20)
383
			if (!compat20)
Lines 1445-1450 mm_answer_keyverify(int sock, Buffer *m) Link Here
1445
	debug3("%s: key %p signature %s",
1458
	debug3("%s: key %p signature %s",
1446
	    __func__, key, (verified == 1) ? "verified" : "unverified");
1459
	    __func__, key, (verified == 1) ? "verified" : "unverified");
1447
1460
1461
	if (verified == 1)
1462
		authctxt->last_details = sshkey_format_oneline(key,
1463
		    options.fingerprint_hash);
1464
1448
	/* If auth was successful then record key to ensure it isn't reused */
1465
	/* If auth was successful then record key to ensure it isn't reused */
1449
	if (verified == 1 && key_blobtype == MM_USERKEY)
1466
	if (verified == 1 && key_blobtype == MM_USERKEY)
1450
		auth2_record_userkey(authctxt, key);
1467
		auth2_record_userkey(authctxt, key);
(-)a/session.c (+7 lines)
Lines 1308-1313 do_setup_env(Session *s, const char *shell) Link Here
1308
	}
1308
	}
1309
#endif /* USE_PAM */
1309
#endif /* USE_PAM */
1310
1310
1311
	if (s->authctxt->auth_details)
1312
		child_set_env(&env, &envsize, "SSH_USER_AUTH",
1313
		     s->authctxt->auth_details);
1314
1311
	if (auth_sock_name != NULL)
1315
	if (auth_sock_name != NULL)
1312
		child_set_env(&env, &envsize, SSH_AUTHSOCKET_ENV_NAME,
1316
		child_set_env(&env, &envsize, SSH_AUTHSOCKET_ENV_NAME,
1313
		    auth_sock_name);
1317
		    auth_sock_name);
Lines 2741-2746 do_cleanup(Authctxt *authctxt) Link Here
2741
	if (authctxt == NULL)
2745
	if (authctxt == NULL)
2742
		return;
2746
		return;
2743
2747
2748
	free(authctxt->auth_details);
2749
	authctxt->auth_details = NULL;
2750
2744
#ifdef USE_PAM
2751
#ifdef USE_PAM
2745
	if (options.use_pam) {
2752
	if (options.use_pam) {
2746
		sshpam_cleanup();
2753
		sshpam_cleanup();
(-)a/ssh.1 (+4 lines)
Lines 1391-1396 server IP address, and server port number. Link Here
1391
This variable contains the original command line if a forced command
1391
This variable contains the original command line if a forced command
1392
is executed.
1392
is executed.
1393
It can be used to extract the original arguments.
1393
It can be used to extract the original arguments.
1394
.It Ev SSH_USER_AUTH
1395
This variable contains, for SSH2 only, a comma-separated list of authentication
1396
methods that were successfuly used to authenticate. When possible, these
1397
methods are extended with detailed information on the credential used.
1394
.It Ev SSH_TTY
1398
.It Ev SSH_TTY
1395
This is set to the name of the tty (path to the device) associated
1399
This is set to the name of the tty (path to the device) associated
1396
with the current shell or command.
1400
with the current shell or command.
(-)a/sshkey.c (+25 lines)
Lines 58-63 Link Here
58
#define SSHKEY_INTERNAL
58
#define SSHKEY_INTERNAL
59
#include "sshkey.h"
59
#include "sshkey.h"
60
#include "match.h"
60
#include "match.h"
61
#include "xmalloc.h"
61
62
62
/* openssh private key file format */
63
/* openssh private key file format */
63
#define MARK_BEGIN		"-----BEGIN OPENSSH PRIVATE KEY-----\n"
64
#define MARK_BEGIN		"-----BEGIN OPENSSH PRIVATE KEY-----\n"
Lines 1189-1194 sshkey_fingerprint(const struct sshkey *k, int dgst_alg, Link Here
1189
	return retval;
1190
	return retval;
1190
}
1191
}
1191
1192
1193
char *
1194
sshkey_format_oneline(const struct sshkey *key, int dgst_alg)
1195
{
1196
	char *fp, *result;
1197
1198
	if (sshkey_is_cert(key)) {
1199
		fp = sshkey_fingerprint(key->cert->signature_key, dgst_alg,
1200
		    SSH_FP_DEFAULT);
1201
		xasprintf(&result, "%s ID %s (serial %llu) CA %s %s",
1202
		    sshkey_type(key), key->cert->key_id,
1203
		    (unsigned long long)key->cert->serial,
1204
		    sshkey_type(key->cert->signature_key),
1205
		    fp == NULL ? "(null)" : fp);
1206
		free(fp);
1207
	} else {
1208
		fp = sshkey_fingerprint(key, dgst_alg, SSH_FP_DEFAULT);
1209
		xasprintf(&result, "%s %s", sshkey_type(key),
1210
		    fp == NULL ? "(null)" : fp);
1211
		free(fp);
1212
	}
1213
1214
	return result;
1215
}
1216
1192
#ifdef WITH_SSH1
1217
#ifdef WITH_SSH1
1193
/*
1218
/*
1194
 * Reads a multiple-precision integer in decimal from the buffer, and advances
1219
 * Reads a multiple-precision integer in decimal from the buffer, and advances
(-)a/sshkey.h (+1 lines)
Lines 123-128 char *sshkey_fingerprint(const struct sshkey *, Link Here
123
    int, enum sshkey_fp_rep);
123
    int, enum sshkey_fp_rep);
124
int		 sshkey_fingerprint_raw(const struct sshkey *k,
124
int		 sshkey_fingerprint_raw(const struct sshkey *k,
125
    int, u_char **retp, size_t *lenp);
125
    int, u_char **retp, size_t *lenp);
126
char		*sshkey_format_oneline(const struct sshkey *k, int dgst_alg);
126
const char	*sshkey_type(const struct sshkey *);
127
const char	*sshkey_type(const struct sshkey *);
127
const char	*sshkey_cert_type(const struct sshkey *);
128
const char	*sshkey_cert_type(const struct sshkey *);
128
int		 sshkey_write(const struct sshkey *, FILE *);
129
int		 sshkey_write(const struct sshkey *, FILE *);

Return to bug 2408