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

Collapse All | Expand All

(-)a/auth-pam.c (-5 / +8 lines)
Lines 670-675 sshpam_init_ctx(Authctxt *authctxt) Link Here
670
{
670
{
671
	struct pam_ctxt *ctxt;
671
	struct pam_ctxt *ctxt;
672
	int socks[2];
672
	int socks[2];
673
	char *auth_info;
673
674
674
	debug3("PAM: %s entering", __func__);
675
	debug3("PAM: %s entering", __func__);
675
	/*
676
	/*
Lines 685-690 sshpam_init_ctx(Authctxt *authctxt) Link Here
685
		return (NULL);
686
		return (NULL);
686
	}
687
	}
687
688
689
	if (authctxt->session_info != NULL &&
690
	    (auth_info = sshbuf_dup_string(authctxt->session_info)) != NULL) {
691
		do_pam_putenv("SSH_USER_AUTH", auth_info);
692
		free(auth_info);
693
	}
694
688
	ctxt = xcalloc(1, sizeof *ctxt);
695
	ctxt = xcalloc(1, sizeof *ctxt);
689
696
690
	/* Start the authentication thread */
697
	/* Start the authentication thread */
Lines 1091-1102 do_pam_putenv(char *name, char *value) Link Here
1091
	int ret = 1;
1098
	int ret = 1;
1092
#ifdef HAVE_PAM_PUTENV
1099
#ifdef HAVE_PAM_PUTENV
1093
	char *compound;
1100
	char *compound;
1094
	size_t len;
1095
1096
	len = strlen(name) + strlen(value) + 2;
1097
	compound = xmalloc(len);
1098
1101
1099
	snprintf(compound, len, "%s=%s", name, value);
1102
	xasprintf(&compound, "%s=%s", name, value);
1100
	ret = pam_putenv(sshpam_handle, compound);
1103
	ret = pam_putenv(sshpam_handle, compound);
1101
	free(compound);
1104
	free(compound);
1102
#endif
1105
#endif
(-)a/auth.c (-17 / +43 lines)
Lines 267-287 allowed_user(struct passwd * pw) Link Here
267
	return 1;
267
	return 1;
268
}
268
}
269
269
270
void
270
/*
271
auth_info(Authctxt *authctxt, const char *fmt, ...)
271
 * Formats any key left in authctxt->auth_method_key for inclusion in
272
 * auth_log()'s message. Also includes authxtct->auth_method_info if present.
273
 */
274
static char *
275
format_method_key(Authctxt *authctxt)
272
{
276
{
273
	va_list ap;
277
	const struct sshkey *key = authctxt->auth_method_key;
274
        int i;
278
	const char *methinfo = authctxt->auth_method_info;
275
279
	char *fp, *ret = NULL;
276
	free(authctxt->info);
277
	authctxt->info = NULL;
278
280
279
	va_start(ap, fmt);
281
	if (key == NULL)
280
	i = vasprintf(&authctxt->info, fmt, ap);
282
		return NULL;
281
	va_end(ap);
282
283
283
	if (i < 0 || authctxt->info == NULL)
284
	if (key_is_cert(key)) {
284
		fatal("vasprintf failed");
285
		fp = sshkey_fingerprint(key->cert->signature_key,
286
		    options.fingerprint_hash, SSH_FP_DEFAULT);
287
		xasprintf(&ret, "%s ID %s (serial %llu) CA %s %s%s%s", 
288
		    sshkey_type(key), key->cert->key_id,
289
		    (unsigned long long)key->cert->serial,
290
		    sshkey_type(key->cert->signature_key),
291
		    fp == NULL ? "(null)" : fp,
292
		    methinfo == NULL ? "" : ", ",
293
		    methinfo == NULL ? "" : methinfo);
294
		free(fp);
295
	} else {
296
		fp = sshkey_fingerprint(key, options.fingerprint_hash,
297
		    SSH_FP_DEFAULT);
298
		xasprintf(&ret, "%s %s%s%s", sshkey_type(key),
299
		    fp == NULL ? "(null)" : fp,
300
		    methinfo == NULL ? "" : ", ",
301
		    methinfo == NULL ? "" : methinfo);
302
		free(fp);
303
	}
304
	return ret;
285
}
305
}
286
306
287
void
307
void
Lines 290-296 auth_log(Authctxt *authctxt, int authenticated, int partial, Link Here
290
{
310
{
291
	struct ssh *ssh = active_state; /* XXX */
311
	struct ssh *ssh = active_state; /* XXX */
292
	void (*authlog) (const char *fmt,...) = verbose;
312
	void (*authlog) (const char *fmt,...) = verbose;
293
	char *authmsg;
313
	const char *authmsg;
314
	char *extra = NULL;
294
315
295
	if (use_privsep && !mm_is_monitor() && !authctxt->postponed)
316
	if (use_privsep && !mm_is_monitor() && !authctxt->postponed)
296
		return;
317
		return;
Lines 309-314 auth_log(Authctxt *authctxt, int authenticated, int partial, Link Here
309
	else
330
	else
310
		authmsg = authenticated ? "Accepted" : "Failed";
331
		authmsg = authenticated ? "Accepted" : "Failed";
311
332
333
	if ((extra = format_method_key(authctxt)) == NULL) {
334
		if (authctxt->auth_method_info != NULL)
335
			extra = xstrdup(authctxt->auth_method_info);
336
	}
337
312
	authlog("%s %s%s%s for %s%.100s from %.200s port %d ssh2%s%s",
338
	authlog("%s %s%s%s for %s%.100s from %.200s port %d ssh2%s%s",
313
	    authmsg,
339
	    authmsg,
314
	    method,
340
	    method,
Lines 317-326 auth_log(Authctxt *authctxt, int authenticated, int partial, Link Here
317
	    authctxt->user,
343
	    authctxt->user,
318
	    ssh_remote_ipaddr(ssh),
344
	    ssh_remote_ipaddr(ssh),
319
	    ssh_remote_port(ssh),
345
	    ssh_remote_port(ssh),
320
	    authctxt->info != NULL ? ": " : "",
346
	    extra != NULL ? ": " : "",
321
	    authctxt->info != NULL ? authctxt->info : "");
347
	    extra != NULL ? extra : "");
322
	free(authctxt->info);
323
	authctxt->info = NULL;
324
348
325
#ifdef CUSTOM_FAILED_LOGIN
349
#ifdef CUSTOM_FAILED_LOGIN
326
	if (authenticated == 0 && !authctxt->postponed &&
350
	if (authenticated == 0 && !authctxt->postponed &&
Lines 340-345 auth_log(Authctxt *authctxt, int authenticated, int partial, Link Here
340
	if (authenticated == 0 && !authctxt->postponed)
364
	if (authenticated == 0 && !authctxt->postponed)
341
		audit_event(audit_classify_auth(method));
365
		audit_event(audit_classify_auth(method));
342
#endif
366
#endif
367
368
	free(extra);
343
}
369
}
344
370
345
371
(-)a/auth.h (-14 / +30 lines)
Lines 62-74 struct Authctxt { Link Here
62
	char		*service;
62
	char		*service;
63
	struct passwd	*pw;		/* set if 'valid' */
63
	struct passwd	*pw;		/* set if 'valid' */
64
	char		*style;
64
	char		*style;
65
66
	/* Method lists for multiple authentication */
67
	char		**auth_methods;	/* modified from server config */
68
	u_int		 num_auth_methods;
69
70
	/* Authentication method-specific data */
71
	void		*methoddata;
65
	void		*kbdintctxt;
72
	void		*kbdintctxt;
66
	char		*info;		/* Extra info for next auth_log */
67
#ifdef BSD_AUTH
73
#ifdef BSD_AUTH
68
	auth_session_t	*as;
74
	auth_session_t	*as;
69
#endif
75
#endif
70
	char		**auth_methods;	/* modified from server config */
71
	u_int		 num_auth_methods;
72
#ifdef KRB5
76
#ifdef KRB5
73
	krb5_context	 krb5_ctx;
77
	krb5_context	 krb5_ctx;
74
	krb5_ccache	 krb5_fwd_ccache;
78
	krb5_ccache	 krb5_fwd_ccache;
Lines 76-86 struct Authctxt { Link Here
76
	char		*krb5_ticket_file;
80
	char		*krb5_ticket_file;
77
	char		*krb5_ccname;
81
	char		*krb5_ccname;
78
#endif
82
#endif
79
	Buffer		*loginmsg;
80
	void		*methoddata;
81
83
82
	struct sshkey	**prev_userkeys;
84
	/* Authentication keys already used; these will be refused henceforth */
83
	u_int		 nprev_userkeys;
85
	struct sshkey	**prev_keys;
86
	u_int		 nprev_keys;
87
88
	/* Last used key and ancilliary information from active auth method */
89
	struct sshkey	*auth_method_key;
90
	char		*auth_method_info;
91
92
	/* Information exposed to session */
93
	Buffer		*loginmsg;	/* Messages to be displayed to pty */
94
	struct sshbuf	*session_info;	/* Auth info for environment */
84
};
95
};
85
/*
96
/*
86
 * Every authentication method has to handle authentication requests for
97
 * Every authentication method has to handle authentication requests for
Lines 119-128 int auth_password(Authctxt *, const char *); Link Here
119
130
120
int	 hostbased_key_allowed(struct passwd *, const char *, char *, Key *);
131
int	 hostbased_key_allowed(struct passwd *, const char *, char *, Key *);
121
int	 user_key_allowed(struct passwd *, Key *, int);
132
int	 user_key_allowed(struct passwd *, Key *, int);
122
void	 pubkey_auth_info(Authctxt *, const Key *, const char *, ...)
133
int	 auth2_key_already_used(Authctxt *, const struct sshkey *);
123
	    __attribute__((__format__ (printf, 3, 4)));
134
124
void	 auth2_record_userkey(Authctxt *, struct sshkey *);
135
/*
125
int	 auth2_userkey_already_used(Authctxt *, struct sshkey *);
136
 * Handling auth method-specific information for logging and prevention
137
 * of key reuse during multiple authentication.
138
 */
139
void	 auth2_authctxt_reset_info(Authctxt *);
140
void	 auth2_record_key(Authctxt *, int, const struct sshkey *);
141
void	 auth2_record_info(Authctxt *authctxt, const char *, ...)
142
	    __attribute__((__format__ (printf, 2, 3)))
143
	    __attribute__((__nonnull__ (2)));
144
void	 auth2_update_session_info(Authctxt *, const char *, const char *);
126
145
127
struct stat;
146
struct stat;
128
int	 auth_secure_path(const char *, struct stat *, const char *, uid_t,
147
int	 auth_secure_path(const char *, struct stat *, const char *, uid_t,
Lines 149-157 void disable_forwarding(void); Link Here
149
168
150
void	do_authentication2(Authctxt *);
169
void	do_authentication2(Authctxt *);
151
170
152
void	auth_info(Authctxt *authctxt, const char *, ...)
153
	    __attribute__((__format__ (printf, 2, 3)))
154
	    __attribute__((__nonnull__ (2)));
155
void	auth_log(Authctxt *, int, int, const char *, const char *);
171
void	auth_log(Authctxt *, int, int, const char *, const char *);
156
void	auth_maxtries_exceeded(Authctxt *) __attribute__((noreturn));
172
void	auth_maxtries_exceeded(Authctxt *) __attribute__((noreturn));
157
void	userauth_finish(Authctxt *, int, const char *, const char *);
173
void	userauth_finish(Authctxt *, int, const char *, const char *);
(-)a/auth2-gss.c (+10 lines)
Lines 227-232 input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt) Link Here
227
{
227
{
228
	Authctxt *authctxt = ctxt;
228
	Authctxt *authctxt = ctxt;
229
	int authenticated;
229
	int authenticated;
230
	const char *displayname;
230
231
231
	if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep))
232
	if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep))
232
		fatal("No authentication or GSSAPI context");
233
		fatal("No authentication or GSSAPI context");
Lines 240-245 input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt) Link Here
240
241
241
	authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user));
242
	authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user));
242
243
244
	if ((!use_privsep || mm_is_monitor()) &&
245
	    (displayname = ssh_gssapi_displayname()) != NULL)
246
		auth2_record_info(authctxt, "%s", displayname);
247
243
	authctxt->postponed = 0;
248
	authctxt->postponed = 0;
244
	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
249
	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
245
	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL);
250
	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL);
Lines 258-263 input_gssapi_mic(int type, u_int32_t plen, void *ctxt) Link Here
258
	Buffer b;
263
	Buffer b;
259
	gss_buffer_desc mic, gssbuf;
264
	gss_buffer_desc mic, gssbuf;
260
	u_int len;
265
	u_int len;
266
	const char *displayname;
261
267
262
	if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep))
268
	if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep))
263
		fatal("No authentication or GSSAPI context");
269
		fatal("No authentication or GSSAPI context");
Lines 281-286 input_gssapi_mic(int type, u_int32_t plen, void *ctxt) Link Here
281
	buffer_free(&b);
287
	buffer_free(&b);
282
	free(mic.value);
288
	free(mic.value);
283
289
290
	if ((!use_privsep || mm_is_monitor()) &&
291
	    (displayname = ssh_gssapi_displayname()) != NULL)
292
		auth2_record_info(authctxt, "%s", displayname);
293
284
	authctxt->postponed = 0;
294
	authctxt->postponed = 0;
285
	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
295
	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
286
	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL);
296
	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL);
(-)a/auth2-hostbased.c (-5 / +5 lines)
Lines 132-152 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
	auth2_record_info(authctxt,
136
	    "client user \"%.100s\", client host \"%.100s\"", cuser, chost);
136
	    "client user \"%.100s\", client host \"%.100s\"", cuser, chost);
137
137
138
	/* test for allowed key and correct signature */
138
	/* test for allowed key and correct signature */
139
	authenticated = 0;
139
	authenticated = 0;
140
	if (PRIVSEP(hostbased_key_allowed(authctxt->pw, cuser, chost, key)) &&
140
	if (PRIVSEP(hostbased_key_allowed(authctxt->pw, cuser, chost, key)) &&
141
	    PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b),
141
	    PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b),
142
			buffer_len(&b))) == 1)
142
	    buffer_len(&b))) == 1)
143
		authenticated = 1;
143
		authenticated = 1;
144
144
145
	auth2_record_key(authctxt, authenticated, key);
145
	buffer_free(&b);
146
	buffer_free(&b);
146
done:
147
done:
147
	debug2("userauth_hostbased: authenticated %d", authenticated);
148
	debug2("%s: authenticated %d", __func__, authenticated);
148
	if (key != NULL)
149
	sshkey_free(key);
149
		key_free(key);
150
	free(pkalg);
150
	free(pkalg);
151
	free(pkblob);
151
	free(pkblob);
152
	free(cuser);
152
	free(cuser);
(-)a/auth2-pubkey.c (-74 / +3 lines)
Lines 127-133 userauth_pubkey(Authctxt *authctxt) Link Here
127
		goto done;
127
		goto done;
128
	}
128
	}
129
	fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_DEFAULT);
129
	fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_DEFAULT);
130
	if (auth2_userkey_already_used(authctxt, key)) {
130
	if (auth2_key_already_used(authctxt, key)) {
131
		logit("refusing previously-used %s key", key_type(key));
131
		logit("refusing previously-used %s key", key_type(key));
132
		goto done;
132
		goto done;
133
	}
133
	}
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);
175
174
176
		/* test for correct signature */
175
		/* test for correct signature */
177
		authenticated = 0;
176
		authenticated = 0;
Lines 179-190 userauth_pubkey(Authctxt *authctxt) Link Here
179
		    PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b),
178
		    PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b),
180
		    buffer_len(&b))) == 1) {
179
		    buffer_len(&b))) == 1) {
181
			authenticated = 1;
180
			authenticated = 1;
182
			/* Record the successful key to prevent reuse */
183
			auth2_record_userkey(authctxt, key);
184
			key = NULL; /* Don't free below */
185
		}
181
		}
186
		buffer_free(&b);
182
		buffer_free(&b);
187
		free(sig);
183
		free(sig);
184
		auth2_record_key(authctxt, authenticated, key);
188
	} else {
185
	} else {
189
		debug("%s: test whether pkalg/pkblob are acceptable for %s %s",
186
		debug("%s: test whether pkalg/pkblob are acceptable for %s %s",
190
		    __func__, sshkey_type(key), fp);
187
		    __func__, sshkey_type(key), fp);
Lines 211-261 userauth_pubkey(Authctxt *authctxt) Link Here
211
		auth_clear_options();
208
		auth_clear_options();
212
done:
209
done:
213
	debug2("%s: authenticated %d pkalg %s", __func__, authenticated, pkalg);
210
	debug2("%s: authenticated %d pkalg %s", __func__, authenticated, pkalg);
214
	if (key != NULL)
211
	sshkey_free(key);
215
		key_free(key);
216
	free(pkalg);
212
	free(pkalg);
217
	free(pkblob);
213
	free(pkblob);
218
	free(fp);
214
	free(fp);
219
	return authenticated;
215
	return authenticated;
220
}
216
}
221
217
222
void
223
pubkey_auth_info(Authctxt *authctxt, const Key *key, const char *fmt, ...)
224
{
225
	char *fp, *extra;
226
	va_list ap;
227
	int i;
228
229
	extra = NULL;
230
	if (fmt != NULL) {
231
		va_start(ap, fmt);
232
		i = vasprintf(&extra, fmt, ap);
233
		va_end(ap);
234
		if (i < 0 || extra == NULL)
235
			fatal("%s: vasprintf failed", __func__);	
236
	}
237
238
	if (key_is_cert(key)) {
239
		fp = sshkey_fingerprint(key->cert->signature_key,
240
		    options.fingerprint_hash, SSH_FP_DEFAULT);
241
		auth_info(authctxt, "%s ID %s (serial %llu) CA %s %s%s%s", 
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);
257
}
258
259
/*
218
/*
260
 * Splits 's' into an argument vector. Handles quoted string and basic
219
 * Splits 's' into an argument vector. Handles quoted string and basic
261
 * escape characters (\\, \", \'). Caller must free the argument vector
220
 * escape characters (\\, \", \'). Caller must free the argument vector
Lines 1119-1154 user_key_allowed(struct passwd *pw, Key *key, int auth_attempt) Link Here
1119
1078
1120
	return success;
1079
	return success;
1121
}
1080
}
1122
1123
/* Records a public key in the list of previously-successful keys */
1124
void
1125
auth2_record_userkey(Authctxt *authctxt, struct sshkey *key)
1126
{
1127
	struct sshkey **tmp;
1128
1129
	if (authctxt->nprev_userkeys >= INT_MAX ||
1130
	    (tmp = reallocarray(authctxt->prev_userkeys,
1131
	    authctxt->nprev_userkeys + 1, sizeof(*tmp))) == NULL)
1132
		fatal("%s: reallocarray failed", __func__);
1133
	authctxt->prev_userkeys = tmp;
1134
	authctxt->prev_userkeys[authctxt->nprev_userkeys] = key;
1135
	authctxt->nprev_userkeys++;
1136
}
1137
1138
/* Checks whether a key has already been used successfully for authentication */
1139
int
1140
auth2_userkey_already_used(Authctxt *authctxt, struct sshkey *key)
1141
{
1142
	u_int i;
1143
1144
	for (i = 0; i < authctxt->nprev_userkeys; i++) {
1145
		if (sshkey_equal_public(key, authctxt->prev_userkeys[i])) {
1146
			return 1;
1147
		}
1148
	}
1149
	return 0;
1150
}
1151
1152
Authmethod method_pubkey = {
1081
Authmethod method_pubkey = {
1153
	"publickey",
1082
	"publickey",
1154
	userauth_pubkey,
1083
	userauth_pubkey,
(-)a/auth2.c (+131 lines)
Lines 50-55 Link Here
50
#include "dispatch.h"
50
#include "dispatch.h"
51
#include "pathnames.h"
51
#include "pathnames.h"
52
#include "buffer.h"
52
#include "buffer.h"
53
#include "ssherr.h"
53
54
54
#ifdef GSSAPI
55
#ifdef GSSAPI
55
#include "ssh-gss.h"
56
#include "ssh-gss.h"
Lines 275-280 input_userauth_request(int type, u_int32_t seq, void *ctxt) Link Here
275
	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL);
276
	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL);
276
#endif
277
#endif
277
278
279
	auth2_authctxt_reset_info(authctxt);
278
	authctxt->postponed = 0;
280
	authctxt->postponed = 0;
279
	authctxt->server_caused_failure = 0;
281
	authctxt->server_caused_failure = 0;
280
282
Lines 322-327 userauth_finish(Authctxt *authctxt, int authenticated, const char *method, Link Here
322
		}
324
		}
323
	}
325
	}
324
326
327
	/* Update information exposed to session */
328
	if (authenticated || partial)
329
		auth2_update_session_info(authctxt, method, submethod);
330
325
	/* Log before sending the reply */
331
	/* Log before sending the reply */
326
	auth_log(authctxt, authenticated, partial, method, submethod);
332
	auth_log(authctxt, authenticated, partial, method, submethod);
327
333
Lines 622-625 auth2_update_methods_lists(Authctxt *authctxt, const char *method, Link Here
622
	return 0;
628
	return 0;
623
}
629
}
624
630
631
/* Reset method-specific information */
632
void auth2_authctxt_reset_info(Authctxt *authctxt)
633
{
634
	sshkey_free(authctxt->auth_method_key);
635
	free(authctxt->auth_method_info);
636
	authctxt->auth_method_key = NULL;
637
	authctxt->auth_method_info = NULL;
638
}
639
640
/* Record auth method-specific information for logs */
641
void
642
auth2_record_info(Authctxt *authctxt, const char *fmt, ...)
643
{
644
	va_list ap;
645
        int i;
646
647
	free(authctxt->auth_method_info);
648
	authctxt->auth_method_info = NULL;
649
650
	va_start(ap, fmt);
651
	i = vasprintf(&authctxt->auth_method_info, fmt, ap);
652
	va_end(ap);
653
654
	if (i < 0 || authctxt->auth_method_info == NULL)
655
		fatal("%s: vasprintf failed", __func__);
656
}
657
658
/*
659
 * Records a public key used in authentication. This is used for logging
660
 * and to ensure that the same key is not subsequently accepted again for
661
 * multiple authentication.
662
 */
663
void
664
auth2_record_key(Authctxt *authctxt, int authenticated,
665
    const struct sshkey *key)
666
{
667
	struct sshkey **tmp, *dup;
668
	int r;
669
670
	if ((r = sshkey_demote(key, &dup)) != 0)
671
		fatal("%s: copy key: %s", __func__, ssh_err(r));
672
	sshkey_free(authctxt->auth_method_key);
673
	authctxt->auth_method_key = dup;
674
675
	if (!authenticated)
676
		return;
677
678
	/* If authenticated, make sure we don't accept this key again */
679
	if ((r = sshkey_demote(key, &dup)) != 0)
680
		fatal("%s: copy key: %s", __func__, ssh_err(r));
681
	if (authctxt->nprev_keys >= INT_MAX ||
682
	    (tmp = reallocarray(authctxt->prev_keys, authctxt->nprev_keys + 1,
683
	    sizeof(*authctxt->prev_keys))) == NULL)
684
		fatal("%s: reallocarray failed", __func__);
685
	authctxt->prev_keys = tmp;
686
	authctxt->prev_keys[authctxt->nprev_keys] = dup;
687
	authctxt->nprev_keys++;
688
689
}
690
691
/* Checks whether a key has already been previously used for authentication */
692
int
693
auth2_key_already_used(Authctxt *authctxt, const struct sshkey *key)
694
{
695
	u_int i;
696
	char *fp;
697
698
	for (i = 0; i < authctxt->nprev_keys; i++) {
699
		if (sshkey_equal_public(key, authctxt->prev_keys[i])) {
700
			fp = sshkey_fingerprint(authctxt->prev_keys[i],
701
			    options.fingerprint_hash, SSH_FP_DEFAULT);
702
			debug3("%s: key already used: %s %s", __func__,
703
			    sshkey_type(authctxt->prev_keys[i]),
704
			    fp == NULL ? "UNKNOWN" : fp);
705
			free(fp);
706
			return 1;
707
		}
708
	}
709
	return 0;
710
}
711
712
/*
713
 * Updates authctxt->session_info with details of authentication. Should be
714
 * whenever an authentication method succeeds.
715
 */
716
void
717
auth2_update_session_info(Authctxt *authctxt, const char *method,
718
    const char *submethod)
719
{
720
	int r;
721
722
	/* Prepare or append to session info buffer */
723
	if (authctxt->session_info == NULL) {
724
		if ((authctxt->session_info = sshbuf_new()) == NULL)
725
			fatal("%s: sshbuf_new", __func__);
726
	} else if ((r = sshbuf_put_u8(authctxt->session_info, '\n')) != 0)
727
		fatal("%s: append: %s", __func__, ssh_err(r));
728
729
	/* Append method[/submethod] */
730
	if ((r = sshbuf_putf(authctxt->session_info, "%s%s%s",
731
	    method, submethod == NULL ? "" : "/",
732
	    submethod == NULL ? "" : submethod)) != 0)
733
		fatal("%s: append method: %s", __func__, ssh_err(r));
734
735
	/* Append key if present */
736
	if (authctxt->auth_method_key != NULL) {
737
		if ((r = sshbuf_put_u8(authctxt->session_info, ' ')) != 0 ||
738
		    (r = sshkey_format_text(authctxt->auth_method_key,
739
		    authctxt->session_info)) != 0)
740
			fatal("%s: append key: %s", __func__, ssh_err(r));
741
	}
742
743
	if (authctxt->auth_method_info != NULL) {
744
		/* Ensure no ambiguity here */
745
		if (strchr(authctxt->auth_method_info, '\n') != NULL)
746
			fatal("%s: auth_method_info contains \\n", __func__);
747
		if ((r = sshbuf_put_u8(authctxt->session_info, ' ')) != 0 ||
748
		    (r = sshbuf_putf(authctxt->session_info, "%s",
749
		    authctxt->auth_method_info)) != 0) {
750
			fatal("%s: append method info: %s",
751
			    __func__, ssh_err(r));
752
		}
753
	}
754
	auth2_authctxt_reset_info(authctxt);
755
}
625
756
(-)a/gss-serv.c (+9 lines)
Lines 393-396 ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic) Link Here
393
	return (ctx->major);
393
	return (ctx->major);
394
}
394
}
395
395
396
/* Privileged */
397
const char *ssh_gssapi_displayname(void)
398
{
399
	if (gssapi_client.displayname.length == 0 ||
400
	    gssapi_client.displayname.value == NULL)
401
		return NULL;
402
	return (char *)gssapi_client.displayname.value;
403
}
404
396
#endif
405
#endif
(-)a/monitor.c (-17 / +23 lines)
Lines 308-313 monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) Link Here
308
		partial = 0;
308
		partial = 0;
309
		auth_method = "unknown";
309
		auth_method = "unknown";
310
		auth_submethod = NULL;
310
		auth_submethod = NULL;
311
		auth2_authctxt_reset_info(authctxt);
312
311
		authenticated = (monitor_read(pmonitor, mon_dispatch, &ent) == 1);
313
		authenticated = (monitor_read(pmonitor, mon_dispatch, &ent) == 1);
312
314
313
		/* Special handling for multiple required authentications */
315
		/* Special handling for multiple required authentications */
Lines 343-348 monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) Link Here
343
#endif
345
#endif
344
		}
346
		}
345
		if (ent->flags & (MON_AUTHDECIDE|MON_ALOG)) {
347
		if (ent->flags & (MON_AUTHDECIDE|MON_ALOG)) {
348
			if (authenticated || partial) {
349
				auth2_update_session_info(authctxt,
350
				    auth_method, auth_submethod);
351
			}
346
			auth_log(authctxt, authenticated, partial,
352
			auth_log(authctxt, authenticated, partial,
347
			    auth_method, auth_submethod);
353
			    auth_method, auth_submethod);
348
			if (!partial && !authenticated)
354
			if (!partial && !authenticated)
Lines 1147-1170 mm_answer_keyallowed(int sock, Buffer *m) Link Here
1147
		switch (type) {
1153
		switch (type) {
1148
		case MM_USERKEY:
1154
		case MM_USERKEY:
1149
			allowed = options.pubkey_authentication &&
1155
			allowed = options.pubkey_authentication &&
1150
			    !auth2_userkey_already_used(authctxt, key) &&
1156
			    !auth2_key_already_used(authctxt, key) &&
1151
			    match_pattern_list(sshkey_ssh_name(key),
1157
			    match_pattern_list(sshkey_ssh_name(key),
1152
			    options.pubkey_key_types, 0) == 1 &&
1158
			    options.pubkey_key_types, 0) == 1 &&
1153
			    user_key_allowed(authctxt->pw, key,
1159
			    user_key_allowed(authctxt->pw, key,
1154
			    pubkey_auth_attempt);
1160
			    pubkey_auth_attempt);
1155
			pubkey_auth_info(authctxt, key, NULL);
1156
			auth_method = "publickey";
1161
			auth_method = "publickey";
1162
			auth2_record_key(authctxt, 0, key);
1157
			if (options.pubkey_authentication &&
1163
			if (options.pubkey_authentication &&
1158
			    (!pubkey_auth_attempt || allowed != 1))
1164
			    (!pubkey_auth_attempt || allowed != 1))
1159
				auth_clear_options();
1165
				auth_clear_options();
1160
			break;
1166
			break;
1161
		case MM_HOSTKEY:
1167
		case MM_HOSTKEY:
1162
			allowed = options.hostbased_authentication &&
1168
			allowed = options.hostbased_authentication &&
1169
			    !auth2_key_already_used(authctxt, key) &&
1163
			    match_pattern_list(sshkey_ssh_name(key),
1170
			    match_pattern_list(sshkey_ssh_name(key),
1164
			    options.hostbased_key_types, 0) == 1 &&
1171
			    options.hostbased_key_types, 0) == 1 &&
1165
			    hostbased_key_allowed(authctxt->pw,
1172
			    hostbased_key_allowed(authctxt->pw,
1166
			    cuser, chost, key);
1173
			    cuser, chost, key);
1167
			pubkey_auth_info(authctxt, key,
1174
			auth2_record_key(authctxt, 0, key);
1175
			auth2_record_info(authctxt,
1168
			    "client user \"%.100s\", client host \"%.100s\"",
1176
			    "client user \"%.100s\", client host \"%.100s\"",
1169
			    cuser, chost);
1177
			    cuser, chost);
1170
			auth_method = "hostbased";
1178
			auth_method = "hostbased";
Lines 1175-1185 mm_answer_keyallowed(int sock, Buffer *m) Link Here
1175
		}
1183
		}
1176
	}
1184
	}
1177
1185
1178
	debug3("%s: key %p is %s",
1186
	debug3("%s: key is %s", __func__, allowed ? "allowed" : "not allowed");
1179
	    __func__, key, allowed ? "allowed" : "not allowed");
1180
1187
1181
	if (key != NULL)
1188
	sshkey_free(key);
1182
		key_free(key);
1183
1189
1184
	/* clear temporarily storage (used by verify) */
1190
	/* clear temporarily storage (used by verify) */
1185
	monitor_reset_key_state();
1191
	monitor_reset_key_state();
Lines 1353-1362 mm_answer_keyverify(int sock, Buffer *m) Link Here
1353
	switch (key_blobtype) {
1359
	switch (key_blobtype) {
1354
	case MM_USERKEY:
1360
	case MM_USERKEY:
1355
		valid_data = monitor_valid_userblob(data, datalen);
1361
		valid_data = monitor_valid_userblob(data, datalen);
1362
		auth_method = "publickey";
1356
		break;
1363
		break;
1357
	case MM_HOSTKEY:
1364
	case MM_HOSTKEY:
1358
		valid_data = monitor_valid_hostbasedblob(data, datalen,
1365
		valid_data = monitor_valid_hostbasedblob(data, datalen,
1359
		    hostbased_cuser, hostbased_chost);
1366
		    hostbased_cuser, hostbased_chost);
1367
		auth_method = "hostbased";
1360
		break;
1368
		break;
1361
	default:
1369
	default:
1362
		valid_data = 0;
1370
		valid_data = 0;
Lines 1366-1388 mm_answer_keyverify(int sock, Buffer *m) Link Here
1366
		fatal("%s: bad signature data blob", __func__);
1374
		fatal("%s: bad signature data blob", __func__);
1367
1375
1368
	verified = key_verify(key, signature, signaturelen, data, datalen);
1376
	verified = key_verify(key, signature, signaturelen, data, datalen);
1369
	debug3("%s: key %p signature %s",
1377
	debug3("%s: %s %p signature %s", __func__, auth_method, key,
1370
	    __func__, key, (verified == 1) ? "verified" : "unverified");
1378
	    (verified == 1) ? "verified" : "unverified");
1371
1379
	auth2_record_key(authctxt, verified == 1, key);
1372
	/* If auth was successful then record key to ensure it isn't reused */
1373
	if (verified == 1 && key_blobtype == MM_USERKEY)
1374
		auth2_record_userkey(authctxt, key);
1375
	else
1376
		key_free(key);
1377
1380
1378
	free(blob);
1381
	free(blob);
1379
	free(signature);
1382
	free(signature);
1380
	free(data);
1383
	free(data);
1381
1384
1382
	auth_method = key_blobtype == MM_USERKEY ? "publickey" : "hostbased";
1383
1384
	monitor_reset_key_state();
1385
	monitor_reset_key_state();
1385
1386
1387
	sshkey_free(key);
1386
	buffer_clear(m);
1388
	buffer_clear(m);
1387
	buffer_put_int(m, verified);
1389
	buffer_put_int(m, verified);
1388
	mm_request_send(sock, MONITOR_ANS_KEYVERIFY, m);
1390
	mm_request_send(sock, MONITOR_ANS_KEYVERIFY, m);
Lines 1774-1779 int Link Here
1774
mm_answer_gss_userok(int sock, Buffer *m)
1776
mm_answer_gss_userok(int sock, Buffer *m)
1775
{
1777
{
1776
	int authenticated;
1778
	int authenticated;
1779
	const char *displayname;
1777
1780
1778
	if (!options.gss_authentication)
1781
	if (!options.gss_authentication)
1779
		fatal("%s: GSSAPI authentication not enabled", __func__);
1782
		fatal("%s: GSSAPI authentication not enabled", __func__);
Lines 1788-1793 mm_answer_gss_userok(int sock, Buffer *m) Link Here
1788
1791
1789
	auth_method = "gssapi-with-mic";
1792
	auth_method = "gssapi-with-mic";
1790
1793
1794
	if ((displayname = ssh_gssapi_displayname()) != NULL)
1795
		auth2_record_info(authctxt, "%s", displayname);
1796
1791
	/* Monitor loop will terminate if authenticated */
1797
	/* Monitor loop will terminate if authenticated */
1792
	return (authenticated);
1798
	return (authenticated);
1793
}
1799
}
(-)a/servconf.c (+11 lines)
Lines 164-169 initialize_server_options(ServerOptions *options) Link Here
164
	options->version_addendum = NULL;
164
	options->version_addendum = NULL;
165
	options->fingerprint_hash = -1;
165
	options->fingerprint_hash = -1;
166
	options->disable_forwarding = -1;
166
	options->disable_forwarding = -1;
167
	options->expose_userauth_info = -1;
167
}
168
}
168
169
169
/* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
170
/* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
Lines 333-338 fill_default_server_options(ServerOptions *options) Link Here
333
		options->fingerprint_hash = SSH_FP_HASH_DEFAULT;
334
		options->fingerprint_hash = SSH_FP_HASH_DEFAULT;
334
	if (options->disable_forwarding == -1)
335
	if (options->disable_forwarding == -1)
335
		options->disable_forwarding = 0;
336
		options->disable_forwarding = 0;
337
	if (options->expose_userauth_info == -1)
338
		options->expose_userauth_info = 0;
336
339
337
	assemble_algorithms(options);
340
	assemble_algorithms(options);
338
341
Lines 418-423 typedef enum { Link Here
418
	sAuthenticationMethods, sHostKeyAgent, sPermitUserRC,
421
	sAuthenticationMethods, sHostKeyAgent, sPermitUserRC,
419
	sStreamLocalBindMask, sStreamLocalBindUnlink,
422
	sStreamLocalBindMask, sStreamLocalBindUnlink,
420
	sAllowStreamLocalForwarding, sFingerprintHash, sDisableForwarding,
423
	sAllowStreamLocalForwarding, sFingerprintHash, sDisableForwarding,
424
	sExposeAuthInfo,
421
	sDeprecated, sIgnore, sUnsupported
425
	sDeprecated, sIgnore, sUnsupported
422
} ServerOpCodes;
426
} ServerOpCodes;
423
427
Lines 561-566 static struct { Link Here
561
	{ "allowstreamlocalforwarding", sAllowStreamLocalForwarding, SSHCFG_ALL },
565
	{ "allowstreamlocalforwarding", sAllowStreamLocalForwarding, SSHCFG_ALL },
562
	{ "fingerprinthash", sFingerprintHash, SSHCFG_GLOBAL },
566
	{ "fingerprinthash", sFingerprintHash, SSHCFG_GLOBAL },
563
	{ "disableforwarding", sDisableForwarding, SSHCFG_ALL },
567
	{ "disableforwarding", sDisableForwarding, SSHCFG_ALL },
568
	{ "exposeauthinfo", sExposeAuthInfo, SSHCFG_ALL },
564
	{ NULL, sBadOption, 0 }
569
	{ NULL, sBadOption, 0 }
565
};
570
};
566
571
Lines 1835-1840 process_server_config_line(ServerOptions *options, char *line, Link Here
1835
			options->fingerprint_hash = value;
1840
			options->fingerprint_hash = value;
1836
		break;
1841
		break;
1837
1842
1843
	case sExposeAuthInfo:
1844
		intptr = &options->expose_userauth_info;
1845
		goto parse_flag;
1846
1838
	case sDeprecated:
1847
	case sDeprecated:
1839
	case sIgnore:
1848
	case sIgnore:
1840
	case sUnsupported:
1849
	case sUnsupported:
Lines 1973-1978 copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) Link Here
1973
	M_CP_INTOPT(allow_streamlocal_forwarding);
1982
	M_CP_INTOPT(allow_streamlocal_forwarding);
1974
	M_CP_INTOPT(allow_agent_forwarding);
1983
	M_CP_INTOPT(allow_agent_forwarding);
1975
	M_CP_INTOPT(disable_forwarding);
1984
	M_CP_INTOPT(disable_forwarding);
1985
	M_CP_INTOPT(expose_userauth_info);
1976
	M_CP_INTOPT(permit_tun);
1986
	M_CP_INTOPT(permit_tun);
1977
	M_CP_INTOPT(fwd_opts.gateway_ports);
1987
	M_CP_INTOPT(fwd_opts.gateway_ports);
1978
	M_CP_INTOPT(fwd_opts.streamlocal_bind_unlink);
1988
	M_CP_INTOPT(fwd_opts.streamlocal_bind_unlink);
Lines 2271-2276 dump_config(ServerOptions *o) Link Here
2271
	dump_cfg_fmtint(sAllowStreamLocalForwarding, o->allow_streamlocal_forwarding);
2281
	dump_cfg_fmtint(sAllowStreamLocalForwarding, o->allow_streamlocal_forwarding);
2272
	dump_cfg_fmtint(sStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink);
2282
	dump_cfg_fmtint(sStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink);
2273
	dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash);
2283
	dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash);
2284
	dump_cfg_fmtint(sExposeAuthInfo, o->expose_userauth_info);
2274
2285
2275
	/* string arguments */
2286
	/* string arguments */
2276
	dump_cfg_string(sPidFile, o->pid_file);
2287
	dump_cfg_string(sPidFile, o->pid_file);
(-)a/servconf.h (+1 lines)
Lines 189-194 typedef struct { Link Here
189
	char   *auth_methods[MAX_AUTH_METHODS];
189
	char   *auth_methods[MAX_AUTH_METHODS];
190
190
191
	int	fingerprint_hash;
191
	int	fingerprint_hash;
192
	int	expose_userauth_info;
192
}       ServerOptions;
193
}       ServerOptions;
193
194
194
/* Information about the incoming connection as used by Match */
195
/* Information about the incoming connection as used by Match */
(-)a/session.c (-22 / +50 lines)
Lines 161-166 login_cap_t *lc; Link Here
161
static int is_child = 0;
161
static int is_child = 0;
162
static int in_chroot = 0;
162
static int in_chroot = 0;
163
163
164
static const char *auth_info = NULL;
165
164
/* Name and directory of socket for authentication agent forwarding. */
166
/* Name and directory of socket for authentication agent forwarding. */
165
static char *auth_sock_name = NULL;
167
static char *auth_sock_name = NULL;
166
static char *auth_sock_dir = NULL;
168
static char *auth_sock_dir = NULL;
Lines 265-271 do_authenticated(Authctxt *authctxt) Link Here
265
267
266
	auth_debug_send();
268
	auth_debug_send();
267
269
270
	auth_info = sshbuf_dup_string(authctxt->session_info);
268
	do_authenticated2(authctxt);
271
	do_authenticated2(authctxt);
272
269
	do_cleanup(authctxt);
273
	do_cleanup(authctxt);
270
}
274
}
271
275
Lines 951-958 read_etc_default_login(char ***env, u_int *envsize, uid_t uid) Link Here
951
}
955
}
952
#endif /* HAVE_ETC_DEFAULT_LOGIN */
956
#endif /* HAVE_ETC_DEFAULT_LOGIN */
953
957
954
void
958
static void
955
copy_environment(char **source, char ***env, u_int *envsize)
959
copy_environment_filtered(char **source, char ***env, u_int *envsize,
960
    const char *blacklist, const char *whitelist)
956
{
961
{
957
	char *var_name, *var_val;
962
	char *var_name, *var_val;
958
	int i;
963
	int i;
Lines 968-980 copy_environment(char **source, char ***env, u_int *envsize) Link Here
968
		}
973
		}
969
		*var_val++ = '\0';
974
		*var_val++ = '\0';
970
975
971
		debug3("Copy environment: %s=%s", var_name, var_val);
976
		/* Apply any filters specified */
972
		child_set_env(env, envsize, var_name, var_val);
977
		if (blacklist != NULL &&
978
		    match_pattern_list(var_name, blacklist, 0) == 1) {
979
			debug3("%s: skipped %s, on blacklist",
980
			    __func__, var_name);
981
		} else if (whitelist != NULL &&
982
		    match_pattern_list(var_name, whitelist, 0) != 1) {
983
			debug3("%s: skipped %s, not on whitelist",
984
			    __func__, var_name);
985
		} else {
986
			debug3("Copy environment: %s=%s", var_name, var_val);
987
			child_set_env(env, envsize, var_name, var_val);
988
		}
973
989
974
		free(var_name);
990
		free(var_name);
975
	}
991
	}
976
}
992
}
977
993
994
void
995
copy_environment(char **source, char ***env, u_int *envsize)
996
{
997
	copy_environment_filtered(source, env, envsize, NULL, NULL);
998
}
999
978
static char **
1000
static char **
979
do_setup_env(Session *s, const char *shell)
1001
do_setup_env(Session *s, const char *shell)
980
{
1002
{
Lines 1001-1006 do_setup_env(Session *s, const char *shell) Link Here
1001
		char **p;
1023
		char **p;
1002
1024
1003
		p = fetch_windows_environment();
1025
		p = fetch_windows_environment();
1026
		/* XXX use whitelist */
1004
		copy_environment(p, &env, &envsize);
1027
		copy_environment(p, &env, &envsize);
1005
		free_windows_environment(p);
1028
		free_windows_environment(p);
1006
	}
1029
	}
Lines 1056-1061 do_setup_env(Session *s, const char *shell) Link Here
1056
	if (getenv("TZ"))
1079
	if (getenv("TZ"))
1057
		child_set_env(&env, &envsize, "TZ", getenv("TZ"));
1080
		child_set_env(&env, &envsize, "TZ", getenv("TZ"));
1058
1081
1082
#ifdef USE_PAM
1083
	/*
1084
	 * Pull in any environment variables that may have
1085
	 * been set by PAM.
1086
	 */
1087
	if (options.use_pam) {
1088
		char **p;
1089
1090
		/* Don't allow SSH_USER_AUTH to leak back from PAM */
1091
		p = fetch_pam_child_environment();
1092
		copy_environment_filtered(p, &env, &envsize,
1093
		    "SSH_USER_AUTH", NULL);
1094
		free_pam_environment(p);
1095
1096
		p = fetch_pam_environment();
1097
		copy_environment_filtered(p, &env, &envsize,
1098
		    "SSH_USER_AUTH", NULL);
1099
		free_pam_environment(p);
1100
	}
1101
#endif /* USE_PAM */
1102
1059
	/* Set custom environment options from RSA authentication. */
1103
	/* Set custom environment options from RSA authentication. */
1060
	while (custom_environment) {
1104
	while (custom_environment) {
1061
		struct envstring *ce = custom_environment;
1105
		struct envstring *ce = custom_environment;
Lines 1085-1090 do_setup_env(Session *s, const char *shell) Link Here
1085
	free(laddr);
1129
	free(laddr);
1086
	child_set_env(&env, &envsize, "SSH_CONNECTION", buf);
1130
	child_set_env(&env, &envsize, "SSH_CONNECTION", buf);
1087
1131
1132
	if (auth_info && options.expose_userauth_info)
1133
		child_set_env(&env, &envsize, "SSH_USER_AUTH", auth_info);
1088
	if (s->ttyfd != -1)
1134
	if (s->ttyfd != -1)
1089
		child_set_env(&env, &envsize, "SSH_TTY", s->tty);
1135
		child_set_env(&env, &envsize, "SSH_TTY", s->tty);
1090
	if (s->term)
1136
	if (s->term)
Lines 1094-1100 do_setup_env(Session *s, const char *shell) Link Here
1094
	if (original_command)
1140
	if (original_command)
1095
		child_set_env(&env, &envsize, "SSH_ORIGINAL_COMMAND",
1141
		child_set_env(&env, &envsize, "SSH_ORIGINAL_COMMAND",
1096
		    original_command);
1142
		    original_command);
1097
1098
#ifdef _UNICOS
1143
#ifdef _UNICOS
1099
	if (cray_tmpdir[0] != '\0')
1144
	if (cray_tmpdir[0] != '\0')
1100
		child_set_env(&env, &envsize, "TMPDIR", cray_tmpdir);
1145
		child_set_env(&env, &envsize, "TMPDIR", cray_tmpdir);
Lines 1126-1148 do_setup_env(Session *s, const char *shell) Link Here
1126
		child_set_env(&env, &envsize, "KRB5CCNAME",
1171
		child_set_env(&env, &envsize, "KRB5CCNAME",
1127
		    s->authctxt->krb5_ccname);
1172
		    s->authctxt->krb5_ccname);
1128
#endif
1173
#endif
1129
#ifdef USE_PAM
1130
	/*
1131
	 * Pull in any environment variables that may have
1132
	 * been set by PAM.
1133
	 */
1134
	if (options.use_pam) {
1135
		char **p;
1136
1137
		p = fetch_pam_child_environment();
1138
		copy_environment(p, &env, &envsize);
1139
		free_pam_environment(p);
1140
1141
		p = fetch_pam_environment();
1142
		copy_environment(p, &env, &envsize);
1143
		free_pam_environment(p);
1144
	}
1145
#endif /* USE_PAM */
1146
1174
1147
	if (auth_sock_name != NULL)
1175
	if (auth_sock_name != NULL)
1148
		child_set_env(&env, &envsize, SSH_AUTHSOCKET_ENV_NAME,
1176
		child_set_env(&env, &envsize, SSH_AUTHSOCKET_ENV_NAME,
(-)a/ssh-gss.h (+1 lines)
Lines 128-133 OM_uint32 ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); Link Here
128
void ssh_gssapi_do_child(char ***, u_int *);
128
void ssh_gssapi_do_child(char ***, u_int *);
129
void ssh_gssapi_cleanup_creds(void);
129
void ssh_gssapi_cleanup_creds(void);
130
void ssh_gssapi_storecreds(void);
130
void ssh_gssapi_storecreds(void);
131
const char *ssh_gssapi_displayname(void);
131
132
132
#endif /* GSSAPI */
133
#endif /* GSSAPI */
133
134
(-)a/sshkey.c (-1 / +1 lines)
Lines 1331-1337 sshkey_to_base64(const struct sshkey *key, char **b64p) Link Here
1331
	return r;
1331
	return r;
1332
}
1332
}
1333
1333
1334
static int
1334
int
1335
sshkey_format_text(const struct sshkey *key, struct sshbuf *b)
1335
sshkey_format_text(const struct sshkey *key, struct sshbuf *b)
1336
{
1336
{
1337
	int r = SSH_ERR_INTERNAL_ERROR;
1337
	int r = SSH_ERR_INTERNAL_ERROR;
(-)a/sshkey.h (+1 lines)
Lines 124-129 int sshkey_fingerprint_raw(const struct sshkey *k, Link Here
124
    int, u_char **retp, size_t *lenp);
124
    int, u_char **retp, size_t *lenp);
125
const char	*sshkey_type(const struct sshkey *);
125
const char	*sshkey_type(const struct sshkey *);
126
const char	*sshkey_cert_type(const struct sshkey *);
126
const char	*sshkey_cert_type(const struct sshkey *);
127
int		 sshkey_format_text(const struct sshkey *, struct sshbuf *);
127
int		 sshkey_write(const struct sshkey *, FILE *);
128
int		 sshkey_write(const struct sshkey *, FILE *);
128
int		 sshkey_read(struct sshkey *, char **);
129
int		 sshkey_read(struct sshkey *, char **);
129
u_int		 sshkey_size(const struct sshkey *);
130
u_int		 sshkey_size(const struct sshkey *);

Return to bug 2408