summaryrefslogtreecommitdiff
path: root/gss-serv-krb5.c
diff options
context:
space:
mode:
authorSimon Wilkinson <simon@sxw.org.uk>2014-02-09 16:09:48 +0000
committerColin Watson <cjwatson@debian.org>2014-02-09 16:16:58 +0000
commit950be7e1b1a01ee9b25e2a72726a6370b8acacb6 (patch)
tree64829a84f903d7e2d3270c43e3f80df7db2a6a10 /gss-serv-krb5.c
parentee196dab7c5f97f0b80c8099343a375bead92010 (diff)
GSSAPI key exchange support
This patch has been rejected upstream: "None of the OpenSSH developers are in favour of adding this, and this situation has not changed for several years. This is not a slight on Simon's patch, which is of fine quality, but just that a) we don't trust GSSAPI implementations that much and b) we don't like adding new KEX since they are pre-auth attack surface. This one is particularly scary, since it requires hooks out to typically root-owned system resources." However, quite a lot of people rely on this in Debian, and it's better to have it merged into the main openssh package rather than having separate -krb5 packages (as we used to have). It seems to have a generally good security history. Bug: https://bugzilla.mindrot.org/show_bug.cgi?id=1242 Last-Updated: 2013-11-09 Patch-Name: gssapi.patch
Diffstat (limited to 'gss-serv-krb5.c')
-rw-r--r--gss-serv-krb5.c84
1 files changed, 78 insertions, 6 deletions
diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c
index 87f26831a..c55446a0b 100644
--- a/gss-serv-krb5.c
+++ b/gss-serv-krb5.c
@@ -1,7 +1,7 @@
1/* $OpenBSD: gss-serv-krb5.c,v 1.8 2013/07/20 01:55:13 djm Exp $ */ 1/* $OpenBSD: gss-serv-krb5.c,v 1.8 2013/07/20 01:55:13 djm Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. 4 * Copyright (c) 2001-2007 Simon Wilkinson. All rights reserved.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
@@ -122,6 +122,7 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client)
122 OM_uint32 maj_status, min_status; 122 OM_uint32 maj_status, min_status;
123 int len; 123 int len;
124 const char *errmsg; 124 const char *errmsg;
125 const char *new_ccname;
125 126
126 if (client->creds == NULL) { 127 if (client->creds == NULL) {
127 debug("No credentials stored"); 128 debug("No credentials stored");
@@ -174,11 +175,16 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client)
174 return; 175 return;
175 } 176 }
176 177
177 client->store.filename = xstrdup(krb5_cc_get_name(krb_context, ccache)); 178 new_ccname = krb5_cc_get_name(krb_context, ccache);
179
178 client->store.envvar = "KRB5CCNAME"; 180 client->store.envvar = "KRB5CCNAME";
179 len = strlen(client->store.filename) + 6; 181#ifdef USE_CCAPI
180 client->store.envval = xmalloc(len); 182 xasprintf(&client->store.envval, "API:%s", new_ccname);
181 snprintf(client->store.envval, len, "FILE:%s", client->store.filename); 183 client->store.filename = NULL;
184#else
185 xasprintf(&client->store.envval, "FILE:%s", new_ccname);
186 client->store.filename = xstrdup(new_ccname);
187#endif
182 188
183#ifdef USE_PAM 189#ifdef USE_PAM
184 if (options.use_pam) 190 if (options.use_pam)
@@ -190,6 +196,71 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client)
190 return; 196 return;
191} 197}
192 198
199int
200ssh_gssapi_krb5_updatecreds(ssh_gssapi_ccache *store,
201 ssh_gssapi_client *client)
202{
203 krb5_ccache ccache = NULL;
204 krb5_principal principal = NULL;
205 char *name = NULL;
206 krb5_error_code problem;
207 OM_uint32 maj_status, min_status;
208
209 if ((problem = krb5_cc_resolve(krb_context, store->envval, &ccache))) {
210 logit("krb5_cc_resolve(): %.100s",
211 krb5_get_err_text(krb_context, problem));
212 return 0;
213 }
214
215 /* Find out who the principal in this cache is */
216 if ((problem = krb5_cc_get_principal(krb_context, ccache,
217 &principal))) {
218 logit("krb5_cc_get_principal(): %.100s",
219 krb5_get_err_text(krb_context, problem));
220 krb5_cc_close(krb_context, ccache);
221 return 0;
222 }
223
224 if ((problem = krb5_unparse_name(krb_context, principal, &name))) {
225 logit("krb5_unparse_name(): %.100s",
226 krb5_get_err_text(krb_context, problem));
227 krb5_free_principal(krb_context, principal);
228 krb5_cc_close(krb_context, ccache);
229 return 0;
230 }
231
232
233 if (strcmp(name,client->exportedname.value)!=0) {
234 debug("Name in local credentials cache differs. Not storing");
235 krb5_free_principal(krb_context, principal);
236 krb5_cc_close(krb_context, ccache);
237 krb5_free_unparsed_name(krb_context, name);
238 return 0;
239 }
240 krb5_free_unparsed_name(krb_context, name);
241
242 /* Name matches, so lets get on with it! */
243
244 if ((problem = krb5_cc_initialize(krb_context, ccache, principal))) {
245 logit("krb5_cc_initialize(): %.100s",
246 krb5_get_err_text(krb_context, problem));
247 krb5_free_principal(krb_context, principal);
248 krb5_cc_close(krb_context, ccache);
249 return 0;
250 }
251
252 krb5_free_principal(krb_context, principal);
253
254 if ((maj_status = gss_krb5_copy_ccache(&min_status, client->creds,
255 ccache))) {
256 logit("gss_krb5_copy_ccache() failed. Sorry!");
257 krb5_cc_close(krb_context, ccache);
258 return 0;
259 }
260
261 return 1;
262}
263
193ssh_gssapi_mech gssapi_kerberos_mech = { 264ssh_gssapi_mech gssapi_kerberos_mech = {
194 "toWM5Slw5Ew8Mqkay+al2g==", 265 "toWM5Slw5Ew8Mqkay+al2g==",
195 "Kerberos", 266 "Kerberos",
@@ -197,7 +268,8 @@ ssh_gssapi_mech gssapi_kerberos_mech = {
197 NULL, 268 NULL,
198 &ssh_gssapi_krb5_userok, 269 &ssh_gssapi_krb5_userok,
199 NULL, 270 NULL,
200 &ssh_gssapi_krb5_storecreds 271 &ssh_gssapi_krb5_storecreds,
272 &ssh_gssapi_krb5_updatecreds
201}; 273};
202 274
203#endif /* KRB5 */ 275#endif /* KRB5 */