summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--auth-krb4.c362
-rw-r--r--auth-passwd.c29
-rw-r--r--auth.h53
-rw-r--r--auth1.c109
-rw-r--r--readconf.c47
-rw-r--r--readconf.h11
-rw-r--r--servconf.c43
-rw-r--r--servconf.h10
-rw-r--r--session.c92
-rw-r--r--sshconnect1.c448
-rw-r--r--sshd.c19
12 files changed, 775 insertions, 455 deletions
diff --git a/ChangeLog b/ChangeLog
index def04ff41..58d21ac55 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -54,6 +54,11 @@
54 prototype pedant. not very creative... 54 prototype pedant. not very creative...
55 - () -> (void) 55 - () -> (void)
56 - no variable names 56 - no variable names
57 - dugsong@cvs.openbsd.org 2001/06/26 16:15:25
58 [auth1.c auth.h auth-krb4.c auth-passwd.c readconf.c readconf.h
59 servconf.c servconf.h session.c sshconnect1.c sshd.c]
60 Kerberos v5 support for SSH1, mostly from Assar Westerlund
61 <assar@freebsd.org> and Bjorn Gronvall <bg@sics.se>. markus@ ok
57 62
5820010629 6320010629
59 - (bal) Removed net_aton() since we don't use it any more 64 - (bal) Removed net_aton() since we don't use it any more
@@ -5881,4 +5886,4 @@
5881 - Wrote replacements for strlcpy and mkdtemp 5886 - Wrote replacements for strlcpy and mkdtemp
5882 - Released 1.0pre1 5887 - Released 1.0pre1
5883 5888
5884$Id: ChangeLog,v 1.1357 2001/07/04 04:07:12 mouring Exp $ 5889$Id: ChangeLog,v 1.1358 2001/07/04 04:21:14 mouring Exp $
diff --git a/auth-krb4.c b/auth-krb4.c
index 8bb6e3d6f..031dcd301 100644
--- a/auth-krb4.c
+++ b/auth-krb4.c
@@ -23,7 +23,7 @@
23 */ 23 */
24 24
25#include "includes.h" 25#include "includes.h"
26RCSID("$OpenBSD: auth-krb4.c,v 1.23 2001/01/22 08:15:00 markus Exp $"); 26RCSID("$OpenBSD: auth-krb4.c,v 1.24 2001/06/26 16:15:22 dugsong Exp $");
27 27
28#include "ssh.h" 28#include "ssh.h"
29#include "ssh1.h" 29#include "ssh1.h"
@@ -31,6 +31,7 @@ RCSID("$OpenBSD: auth-krb4.c,v 1.23 2001/01/22 08:15:00 markus Exp $");
31#include "xmalloc.h" 31#include "xmalloc.h"
32#include "log.h" 32#include "log.h"
33#include "servconf.h" 33#include "servconf.h"
34#include "uidswap.h"
34#include "auth.h" 35#include "auth.h"
35 36
36#ifdef AFS 37#ifdef AFS
@@ -38,70 +39,114 @@ RCSID("$OpenBSD: auth-krb4.c,v 1.23 2001/01/22 08:15:00 markus Exp $");
38#endif 39#endif
39 40
40#ifdef KRB4 41#ifdef KRB4
41char *ticket = NULL;
42
43extern ServerOptions options; 42extern ServerOptions options;
44 43
44static int
45krb4_init(void *context)
46{
47 static int cleanup_registered = 0;
48 Authctxt *authctxt = (Authctxt *)context;
49 const char *tkt_root = TKT_ROOT;
50 struct stat st;
51 int fd;
52
53 if (!authctxt->krb4_ticket_file) {
54 /* Set unique ticket string manually since we're still root. */
55 authctxt->krb4_ticket_file = xmalloc(MAXPATHLEN);
56#ifdef AFS
57 if (lstat("/ticket", &st) != -1)
58 tkt_root = "/ticket/";
59#endif /* AFS */
60 snprintf(authctxt->krb4_ticket_file, MAXPATHLEN, "%s%u_%d",
61 tkt_root, authctxt->pw->pw_uid, getpid());
62 krb_set_tkt_string(authctxt->krb4_ticket_file);
63 }
64 /* Register ticket cleanup in case of fatal error. */
65 if (!cleanup_registered) {
66 fatal_add_cleanup(krb4_cleanup_proc, authctxt);
67 cleanup_registered = 1;
68 }
69 /* Try to create our ticket file. */
70 if ((fd = mkstemp(authctxt->krb4_ticket_file)) != -1) {
71 close(fd);
72 return (1);
73 }
74 /* Ticket file exists - make sure user owns it (just passed ticket). */
75 if (lstat(authctxt->krb4_ticket_file, &st) != -1) {
76 if (st.st_mode == (S_IFREG | S_IRUSR | S_IWUSR) &&
77 st.st_uid == authctxt->pw->pw_uid)
78 return (1);
79 }
80 /* Failure - cancel cleanup function, leaving ticket for inspection. */
81 log("WARNING: bad ticket file %s", authctxt->krb4_ticket_file);
82
83 fatal_remove_cleanup(krb4_cleanup_proc, authctxt);
84 cleanup_registered = 0;
85
86 xfree(authctxt->krb4_ticket_file);
87 authctxt->krb4_ticket_file = NULL;
88
89 return (0);
90}
91
45/* 92/*
46 * try krb4 authentication, 93 * try krb4 authentication,
47 * return 1 on success, 0 on failure, -1 if krb4 is not available 94 * return 1 on success, 0 on failure, -1 if krb4 is not available
48 */ 95 */
49
50int 96int
51auth_krb4_password(struct passwd * pw, const char *password) 97auth_krb4_password(Authctxt *authctxt, const char *password)
52{ 98{
53 AUTH_DAT adata; 99 AUTH_DAT adata;
54 KTEXT_ST tkt; 100 KTEXT_ST tkt;
55 struct hostent *hp; 101 struct hostent *hp;
56 u_long faddr; 102 struct passwd *pw;
57 char localhost[MAXHOSTNAMELEN]; 103 char localhost[MAXHOSTNAMELEN], phost[INST_SZ], realm[REALM_SZ];
58 char phost[INST_SZ]; 104 u_int32_t faddr;
59 char realm[REALM_SZ];
60 int r; 105 int r;
61 106
107 if ((pw = authctxt->pw) == NULL)
108 return (0);
109
62 /* 110 /*
63 * Try Kerberos password authentication only for non-root 111 * Try Kerberos password authentication only for non-root
64 * users and only if Kerberos is installed. 112 * users and only if Kerberos is installed.
65 */ 113 */
66 if (pw->pw_uid != 0 && krb_get_lrealm(realm, 1) == KSUCCESS) { 114 if (pw->pw_uid != 0 && krb_get_lrealm(realm, 1) == KSUCCESS) {
67
68 /* Set up our ticket file. */ 115 /* Set up our ticket file. */
69 if (!krb4_init(pw->pw_uid)) { 116 if (!krb4_init(authctxt)) {
70 log("Couldn't initialize Kerberos ticket file for %s!", 117 log("Couldn't initialize Kerberos ticket file for %s!",
71 pw->pw_name); 118 pw->pw_name);
72 goto kerberos_auth_failure; 119 goto failure;
73 } 120 }
74 /* Try to get TGT using our password. */ 121 /* Try to get TGT using our password. */
75 r = krb_get_pw_in_tkt((char *) pw->pw_name, "", 122 r = krb_get_pw_in_tkt((char *) pw->pw_name, "", realm,
76 realm, "krbtgt", realm, 123 "krbtgt", realm, DEFAULT_TKT_LIFE, (char *)password);
77 DEFAULT_TKT_LIFE, (char *) password);
78 if (r != INTK_OK) { 124 if (r != INTK_OK) {
79 packet_send_debug("Kerberos V4 password " 125 debug("Kerberos v4 password authentication for %s "
80 "authentication for %s failed: %s", 126 "failed: %s", pw->pw_name, krb_err_txt[r]);
81 pw->pw_name, krb_err_txt[r]); 127 goto failure;
82 goto kerberos_auth_failure;
83 } 128 }
84 /* Successful authentication. */ 129 /* Successful authentication. */
85 chown(tkt_string(), pw->pw_uid, pw->pw_gid); 130 chown(tkt_string(), pw->pw_uid, pw->pw_gid);
86 131
87 /* 132 /*
88 * Now that we have a TGT, try to get a local 133 * Now that we have a TGT, try to get a local
89 * "rcmd" ticket to ensure that we are not talking 134 * "rcmd" ticket to ensure that we are not talking
90 * to a bogus Kerberos server. 135 * to a bogus Kerberos server.
91 */ 136 */
92 (void) gethostname(localhost, sizeof(localhost)); 137 gethostname(localhost, sizeof(localhost));
93 (void) strlcpy(phost, (char *) krb_get_phost(localhost), 138 strlcpy(phost, (char *)krb_get_phost(localhost),
94 INST_SZ); 139 sizeof(phost));
95 r = krb_mk_req(&tkt, KRB4_SERVICE_NAME, phost, realm, 33); 140 r = krb_mk_req(&tkt, KRB4_SERVICE_NAME, phost, realm, 33);
96 141
97 if (r == KSUCCESS) { 142 if (r == KSUCCESS) {
98 if (!(hp = gethostbyname(localhost))) { 143 if ((hp = gethostbyname(localhost)) == NULL) {
99 log("Couldn't get local host address!"); 144 log("Couldn't get local host address!");
100 goto kerberos_auth_failure; 145 goto failure;
101 } 146 }
102 memmove((void *) &faddr, (void *) hp->h_addr, 147 memmove((void *)&faddr, (void *)hp->h_addr,
103 sizeof(faddr)); 148 sizeof(faddr));
104 149
105 /* Verify our "rcmd" ticket. */ 150 /* Verify our "rcmd" ticket. */
106 r = krb_rd_req(&tkt, KRB4_SERVICE_NAME, phost, 151 r = krb_rd_req(&tkt, KRB4_SERVICE_NAME, phost,
107 faddr, &adata, ""); 152 faddr, &adata, "");
@@ -110,119 +155,74 @@ auth_krb4_password(struct passwd * pw, const char *password)
110 * Probably didn't have a srvtab on 155 * Probably didn't have a srvtab on
111 * localhost. Disallow login. 156 * localhost. Disallow login.
112 */ 157 */
113 log("Kerberos V4 TGT for %s unverifiable, " 158 log("Kerberos v4 TGT for %s unverifiable, "
114 "no srvtab installed? krb_rd_req: %s", 159 "no srvtab installed? krb_rd_req: %s",
115 pw->pw_name, krb_err_txt[r]); 160 pw->pw_name, krb_err_txt[r]);
116 goto kerberos_auth_failure; 161 goto failure;
117 } else if (r != KSUCCESS) { 162 } else if (r != KSUCCESS) {
118 log("Kerberos V4 %s ticket unverifiable: %s", 163 log("Kerberos v4 %s ticket unverifiable: %s",
119 KRB4_SERVICE_NAME, krb_err_txt[r]); 164 KRB4_SERVICE_NAME, krb_err_txt[r]);
120 goto kerberos_auth_failure; 165 goto failure;
121 } 166 }
122 } else if (r == KDC_PR_UNKNOWN) { 167 } else if (r == KDC_PR_UNKNOWN) {
123 /* 168 /*
124 * Disallow login if no rcmd service exists, and 169 * Disallow login if no rcmd service exists, and
125 * log the error. 170 * log the error.
126 */ 171 */
127 log("Kerberos V4 TGT for %s unverifiable: %s; %s.%s " 172 log("Kerberos v4 TGT for %s unverifiable: %s; %s.%s "
128 "not registered, or srvtab is wrong?", pw->pw_name, 173 "not registered, or srvtab is wrong?", pw->pw_name,
129 krb_err_txt[r], KRB4_SERVICE_NAME, phost); 174 krb_err_txt[r], KRB4_SERVICE_NAME, phost);
130 goto kerberos_auth_failure; 175 goto failure;
131 } else { 176 } else {
132 /* 177 /*
133 * TGT is bad, forget it. Possibly spoofed! 178 * TGT is bad, forget it. Possibly spoofed!
134 */ 179 */
135 packet_send_debug("WARNING: Kerberos V4 TGT " 180 debug("WARNING: Kerberos v4 TGT possibly spoofed "
136 "possibly spoofed for %s: %s", 181 "for %s: %s", pw->pw_name, krb_err_txt[r]);
137 pw->pw_name, krb_err_txt[r]); 182 goto failure;
138 goto kerberos_auth_failure;
139 } 183 }
140
141 /* Authentication succeeded. */ 184 /* Authentication succeeded. */
142 return 1; 185 return (1);
143 186 } else
144kerberos_auth_failure:
145 krb4_cleanup_proc(NULL);
146
147 if (!options.kerberos_or_local_passwd)
148 return 0;
149 } else {
150 /* Logging in as root or no local Kerberos realm. */ 187 /* Logging in as root or no local Kerberos realm. */
151 packet_send_debug("Unable to authenticate to Kerberos."); 188 debug("Unable to authenticate to Kerberos.");
152 } 189
190 failure:
191 krb4_cleanup_proc(authctxt);
192
193 if (!options.kerberos_or_local_passwd)
194 return (0);
195
153 /* Fall back to ordinary passwd authentication. */ 196 /* Fall back to ordinary passwd authentication. */
154 return -1; 197 return (-1);
155} 198}
156 199
157void 200void
158krb4_cleanup_proc(void *ignore) 201krb4_cleanup_proc(void *context)
159{ 202{
203 Authctxt *authctxt = (Authctxt *)context;
160 debug("krb4_cleanup_proc called"); 204 debug("krb4_cleanup_proc called");
161 if (ticket) { 205 if (authctxt->krb4_ticket_file) {
162 (void) dest_tkt(); 206 (void) dest_tkt();
163 xfree(ticket); 207 xfree(authctxt->krb4_ticket_file);
164 ticket = NULL; 208 authctxt->krb4_ticket_file = NULL;
165 }
166}
167
168int
169krb4_init(uid_t uid)
170{
171 static int cleanup_registered = 0;
172 const char *tkt_root = TKT_ROOT;
173 struct stat st;
174 int fd;
175
176 if (!ticket) {
177 /* Set unique ticket string manually since we're still root. */
178 ticket = xmalloc(MAXPATHLEN);
179#ifdef AFS
180 if (lstat("/ticket", &st) != -1)
181 tkt_root = "/ticket/";
182#endif /* AFS */
183 snprintf(ticket, MAXPATHLEN, "%s%u_%d", tkt_root, uid, getpid());
184 (void) krb_set_tkt_string(ticket);
185 }
186 /* Register ticket cleanup in case of fatal error. */
187 if (!cleanup_registered) {
188 fatal_add_cleanup(krb4_cleanup_proc, NULL);
189 cleanup_registered = 1;
190 }
191 /* Try to create our ticket file. */
192 if ((fd = mkstemp(ticket)) != -1) {
193 close(fd);
194 return 1;
195 }
196 /* Ticket file exists - make sure user owns it (just passed ticket). */
197 if (lstat(ticket, &st) != -1) {
198 if (st.st_mode == (S_IFREG | S_IRUSR | S_IWUSR) &&
199 st.st_uid == uid)
200 return 1;
201 } 209 }
202 /* Failure - cancel cleanup function, leaving bad ticket for inspection. */
203 log("WARNING: bad ticket file %s", ticket);
204 fatal_remove_cleanup(krb4_cleanup_proc, NULL);
205 cleanup_registered = 0;
206 xfree(ticket);
207 ticket = NULL;
208
209 return 0;
210} 210}
211 211
212int 212int
213auth_krb4(const char *server_user, KTEXT auth, char **client) 213auth_krb4(Authctxt *authctxt, KTEXT auth, char **client)
214{ 214{
215 AUTH_DAT adat = {0}; 215 AUTH_DAT adat = {0};
216 KTEXT_ST reply; 216 KTEXT_ST reply;
217 Key_schedule schedule;
218 struct sockaddr_in local, foreign;
217 char instance[INST_SZ]; 219 char instance[INST_SZ];
218 int r, s;
219 socklen_t slen; 220 socklen_t slen;
220 u_int cksum; 221 u_int cksum;
221 Key_schedule schedule; 222 int r, s;
222 struct sockaddr_in local, foreign; 223
223
224 s = packet_get_connection_in(); 224 s = packet_get_connection_in();
225 225
226 slen = sizeof(local); 226 slen = sizeof(local);
227 memset(&local, 0, sizeof(local)); 227 memset(&local, 0, sizeof(local));
228 if (getsockname(s, (struct sockaddr *) & local, &slen) < 0) 228 if (getsockname(s, (struct sockaddr *) & local, &slen) < 0)
@@ -235,157 +235,139 @@ auth_krb4(const char *server_user, KTEXT auth, char **client)
235 } 235 }
236 instance[0] = '*'; 236 instance[0] = '*';
237 instance[1] = 0; 237 instance[1] = 0;
238 238
239 /* Get the encrypted request, challenge, and session key. */ 239 /* Get the encrypted request, challenge, and session key. */
240 if ((r = krb_rd_req(auth, KRB4_SERVICE_NAME, instance, 0, &adat, ""))) { 240 if ((r = krb_rd_req(auth, KRB4_SERVICE_NAME, instance,
241 packet_send_debug("Kerberos V4 krb_rd_req: %.100s", krb_err_txt[r]); 241 0, &adat, ""))) {
242 return 0; 242 debug("Kerberos v4 krb_rd_req: %.100s", krb_err_txt[r]);
243 return (0);
243 } 244 }
244 des_key_sched((des_cblock *) adat.session, schedule); 245 des_key_sched((des_cblock *) adat.session, schedule);
245 246
246 *client = xmalloc(MAX_K_NAME_SZ); 247 *client = xmalloc(MAX_K_NAME_SZ);
247 (void) snprintf(*client, MAX_K_NAME_SZ, "%s%s%s@%s", adat.pname, 248 (void) snprintf(*client, MAX_K_NAME_SZ, "%s%s%s@%s", adat.pname,
248 *adat.pinst ? "." : "", adat.pinst, adat.prealm); 249 *adat.pinst ? "." : "", adat.pinst, adat.prealm);
249 250
250 /* Check ~/.klogin authorization now. */ 251 /* Check ~/.klogin authorization now. */
251 if (kuserok(&adat, (char *) server_user) != KSUCCESS) { 252 if (kuserok(&adat, authctxt->user) != KSUCCESS) {
252 packet_send_debug("Kerberos V4 .klogin authorization failed!"); 253 log("Kerberos v4 .klogin authorization failed for %s to "
253 log("Kerberos V4 .klogin authorization failed for %s to account %s", 254 "account %s", *client, authctxt->user);
254 *client, server_user);
255 xfree(*client); 255 xfree(*client);
256 return 0; 256 return (0);
257 } 257 }
258 /* Increment the checksum, and return it encrypted with the 258 /* Increment the checksum, and return it encrypted with the
259 session key. */ 259 session key. */
260 cksum = adat.checksum + 1; 260 cksum = adat.checksum + 1;
261 cksum = htonl(cksum); 261 cksum = htonl(cksum);
262 262
263 /* If we can't successfully encrypt the checksum, we send back an 263 /* If we can't successfully encrypt the checksum, we send back an
264 empty message, admitting our failure. */ 264 empty message, admitting our failure. */
265 if ((r = krb_mk_priv((u_char *) & cksum, reply.dat, sizeof(cksum) + 1, 265 if ((r = krb_mk_priv((u_char *) & cksum, reply.dat, sizeof(cksum) + 1,
266 schedule, &adat.session, &local, &foreign)) < 0) { 266 schedule, &adat.session, &local, &foreign)) < 0) {
267 packet_send_debug("Kerberos V4 mk_priv: (%d) %s", r, krb_err_txt[r]); 267 debug("Kerberos v4 mk_priv: (%d) %s", r, krb_err_txt[r]);
268 reply.dat[0] = 0; 268 reply.dat[0] = 0;
269 reply.length = 0; 269 reply.length = 0;
270 } else 270 } else
271 reply.length = r; 271 reply.length = r;
272 272
273 /* Clear session key. */ 273 /* Clear session key. */
274 memset(&adat.session, 0, sizeof(&adat.session)); 274 memset(&adat.session, 0, sizeof(&adat.session));
275 275
276 packet_start(SSH_SMSG_AUTH_KERBEROS_RESPONSE); 276 packet_start(SSH_SMSG_AUTH_KERBEROS_RESPONSE);
277 packet_put_string((char *) reply.dat, reply.length); 277 packet_put_string((char *) reply.dat, reply.length);
278 packet_send(); 278 packet_send();
279 packet_write_wait(); 279 packet_write_wait();
280 return 1; 280 return (1);
281} 281}
282#endif /* KRB4 */ 282#endif /* KRB4 */
283 283
284#ifdef AFS 284#ifdef AFS
285int 285int
286auth_kerberos_tgt(struct passwd *pw, const char *string) 286auth_krb4_tgt(Authctxt *authctxt, const char *string)
287{ 287{
288 CREDENTIALS creds; 288 CREDENTIALS creds;
289 289 struct passwd *pw;
290 if (pw == NULL) 290
291 goto auth_kerberos_tgt_failure; 291 if ((pw = authctxt->pw) == NULL)
292 goto failure;
293
294 temporarily_use_uid(pw);
295
292 if (!radix_to_creds(string, &creds)) { 296 if (!radix_to_creds(string, &creds)) {
293 log("Protocol error decoding Kerberos V4 tgt"); 297 log("Protocol error decoding Kerberos v4 TGT");
294 packet_send_debug("Protocol error decoding Kerberos V4 tgt"); 298 goto failure;
295 goto auth_kerberos_tgt_failure;
296 } 299 }
297 if (strncmp(creds.service, "", 1) == 0) /* backward compatibility */ 300 if (strncmp(creds.service, "", 1) == 0) /* backward compatibility */
298 strlcpy(creds.service, "krbtgt", sizeof creds.service); 301 strlcpy(creds.service, "krbtgt", sizeof creds.service);
299 302
300 if (strcmp(creds.service, "krbtgt")) { 303 if (strcmp(creds.service, "krbtgt")) {
301 log("Kerberos V4 tgt (%s%s%s@%s) rejected for %s", creds.pname, 304 log("Kerberos v4 TGT (%s%s%s@%s) rejected for %s",
302 creds.pinst[0] ? "." : "", creds.pinst, creds.realm,
303 pw->pw_name);
304 packet_send_debug("Kerberos V4 tgt (%s%s%s@%s) rejected for %s",
305 creds.pname, creds.pinst[0] ? "." : "", creds.pinst, 305 creds.pname, creds.pinst[0] ? "." : "", creds.pinst,
306 creds.realm, pw->pw_name); 306 creds.realm, pw->pw_name);
307 goto auth_kerberos_tgt_failure; 307 goto failure;
308 } 308 }
309 if (!krb4_init(pw->pw_uid)) 309 if (!krb4_init(authctxt))
310 goto auth_kerberos_tgt_failure; 310 goto failure;
311 311
312 if (in_tkt(creds.pname, creds.pinst) != KSUCCESS) 312 if (in_tkt(creds.pname, creds.pinst) != KSUCCESS)
313 goto auth_kerberos_tgt_failure; 313 goto failure;
314 314
315 if (save_credentials(creds.service, creds.instance, creds.realm, 315 if (save_credentials(creds.service, creds.instance, creds.realm,
316 creds.session, creds.lifetime, creds.kvno, 316 creds.session, creds.lifetime, creds.kvno, &creds.ticket_st,
317 &creds.ticket_st, creds.issue_date) != KSUCCESS) { 317 creds.issue_date) != KSUCCESS) {
318 packet_send_debug("Kerberos V4 tgt refused: couldn't save credentials"); 318 debug("Kerberos v4 TGT refused: couldn't save credentials");
319 goto auth_kerberos_tgt_failure; 319 goto failure;
320 } 320 }
321 /* Successful authentication, passed all checks. */ 321 /* Successful authentication, passed all checks. */
322 chown(tkt_string(), pw->pw_uid, pw->pw_gid); 322 chown(tkt_string(), pw->pw_uid, pw->pw_gid);
323 323
324 packet_send_debug("Kerberos V4 tgt accepted (%s.%s@%s, %s%s%s@%s)", 324 debug("Kerberos v4 TGT accepted (%s%s%s@%s)",
325 creds.service, creds.instance, creds.realm, creds.pname, 325 creds.pname, creds.pinst[0] ? "." : "", creds.pinst, creds.realm);
326 creds.pinst[0] ? "." : "", creds.pinst, creds.realm);
327 memset(&creds, 0, sizeof(creds)); 326 memset(&creds, 0, sizeof(creds));
328 packet_start(SSH_SMSG_SUCCESS); 327
329 packet_send(); 328 restore_uid();
330 packet_write_wait(); 329
331 return 1; 330 return (1);
332 331
333auth_kerberos_tgt_failure: 332 failure:
334 krb4_cleanup_proc(NULL); 333 krb4_cleanup_proc(authctxt);
335 memset(&creds, 0, sizeof(creds)); 334 memset(&creds, 0, sizeof(creds));
336 packet_start(SSH_SMSG_FAILURE); 335 restore_uid();
337 packet_send(); 336
338 packet_write_wait(); 337 return (0);
339 return 0;
340} 338}
341 339
342int 340int
343auth_afs_token(struct passwd *pw, const char *token_string) 341auth_afs_token(Authctxt *authctxt, const char *token_string)
344{ 342{
345 CREDENTIALS creds; 343 CREDENTIALS creds;
344 struct passwd *pw;
346 uid_t uid; 345 uid_t uid;
347 346
348 if (pw == NULL) { 347 if ((pw = authctxt->pw) == NULL)
349 /* XXX fake protocol error */ 348 return (0);
350 packet_send_debug("Protocol error decoding AFS token"); 349
351 packet_start(SSH_SMSG_FAILURE);
352 packet_send();
353 packet_write_wait();
354 return 0;
355 }
356 if (!radix_to_creds(token_string, &creds)) { 350 if (!radix_to_creds(token_string, &creds)) {
357 log("Protocol error decoding AFS token"); 351 log("Protocol error decoding AFS token");
358 packet_send_debug("Protocol error decoding AFS token"); 352 return (0);
359 packet_start(SSH_SMSG_FAILURE);
360 packet_send();
361 packet_write_wait();
362 return 0;
363 } 353 }
364 if (strncmp(creds.service, "", 1) == 0) /* backward compatibility */ 354 if (strncmp(creds.service, "", 1) == 0) /* backward compatibility */
365 strlcpy(creds.service, "afs", sizeof creds.service); 355 strlcpy(creds.service, "afs", sizeof creds.service);
366 356
367 if (strncmp(creds.pname, "AFS ID ", 7) == 0) 357 if (strncmp(creds.pname, "AFS ID ", 7) == 0)
368 uid = atoi(creds.pname + 7); 358 uid = atoi(creds.pname + 7);
369 else 359 else
370 uid = pw->pw_uid; 360 uid = pw->pw_uid;
371 361
372 if (kafs_settoken(creds.realm, uid, &creds)) { 362 if (kafs_settoken(creds.realm, uid, &creds)) {
373 log("AFS token (%s@%s) rejected for %s", creds.pname, creds.realm, 363 log("AFS token (%s@%s) rejected for %s",
374 pw->pw_name); 364 creds.pname, creds.realm, pw->pw_name);
375 packet_send_debug("AFS token (%s@%s) rejected for %s", creds.pname,
376 creds.realm, pw->pw_name);
377 memset(&creds, 0, sizeof(creds)); 365 memset(&creds, 0, sizeof(creds));
378 packet_start(SSH_SMSG_FAILURE); 366 return (0);
379 packet_send();
380 packet_write_wait();
381 return 0;
382 } 367 }
383 packet_send_debug("AFS token accepted (%s@%s, %s@%s)", creds.service, 368 debug("AFS token accepted (%s@%s)", creds.pname, creds.realm);
384 creds.realm, creds.pname, creds.realm);
385 memset(&creds, 0, sizeof(creds)); 369 memset(&creds, 0, sizeof(creds));
386 packet_start(SSH_SMSG_SUCCESS); 370
387 packet_send(); 371 return (1);
388 packet_write_wait();
389 return 1;
390} 372}
391#endif /* AFS */ 373#endif /* AFS */
diff --git a/auth-passwd.c b/auth-passwd.c
index d53a9ea2d..988297cb4 100644
--- a/auth-passwd.c
+++ b/auth-passwd.c
@@ -36,7 +36,7 @@
36 */ 36 */
37 37
38#include "includes.h" 38#include "includes.h"
39RCSID("$OpenBSD: auth-passwd.c,v 1.22 2001/03/20 18:57:04 markus Exp $"); 39RCSID("$OpenBSD: auth-passwd.c,v 1.23 2001/06/26 16:15:23 dugsong Exp $");
40 40
41#if !defined(USE_PAM) && !defined(HAVE_OSF_SIA) 41#if !defined(USE_PAM) && !defined(HAVE_OSF_SIA)
42 42
@@ -128,14 +128,14 @@ auth_password(Authctxt *authctxt, const char *password)
128#endif 128#endif
129 if (*password == '\0' && options.permit_empty_passwd == 0) 129 if (*password == '\0' && options.permit_empty_passwd == 0)
130 return 0; 130 return 0;
131#ifdef BSD_AUTH 131#ifdef KRB5
132 if (auth_userokay(pw->pw_name, authctxt->style, "auth-ssh", 132 if (options.kerberos_authentication == 1) {
133 (char *)password) == 0) 133 int ret = auth_krb5_password(authctxt, password);
134 return 0; 134 if (ret == 1 || ret == 0)
135 else 135 return ret;
136 return 1; 136 /* Fall back to ordinary passwd authentication. */
137 }
137#endif 138#endif
138
139#ifdef HAVE_CYGWIN 139#ifdef HAVE_CYGWIN
140 if (is_winnt) { 140 if (is_winnt) {
141 HANDLE hToken = cygwin_logon_user(pw, password); 141 HANDLE hToken = cygwin_logon_user(pw, password);
@@ -146,21 +146,24 @@ auth_password(Authctxt *authctxt, const char *password)
146 return 1; 146 return 1;
147 } 147 }
148#endif 148#endif
149
150#ifdef WITH_AIXAUTHENTICATE 149#ifdef WITH_AIXAUTHENTICATE
151 return (authenticate(pw->pw_name,password,&reenter,&authmsg) == 0); 150 return (authenticate(pw->pw_name,password,&reenter,&authmsg) == 0);
152#endif 151#endif
153
154#ifdef KRB4 152#ifdef KRB4
155 if (options.kerberos_authentication == 1) { 153 if (options.kerberos_authentication == 1) {
156 int ret = auth_krb4_password(pw, password); 154 int ret = auth_krb4_password(authctxt, password);
157 if (ret == 1 || ret == 0) 155 if (ret == 1 || ret == 0)
158 return ret; 156 return ret;
159 /* Fall back to ordinary passwd authentication. */ 157 /* Fall back to ordinary passwd authentication. */
160 } 158 }
161#endif 159#endif
162 160#ifdef BSD_AUTH
163 161 if (auth_userokay(pw->pw_name, authctxt->style, "auth-ssh",
162 (char *)password) == 0)
163 return 0;
164 else
165 return 1;
166#endif
164 pw_password = pw->pw_passwd; 167 pw_password = pw->pw_passwd;
165 168
166 /* 169 /*
diff --git a/auth.h b/auth.h
index a29944113..1c72dffa3 100644
--- a/auth.h
+++ b/auth.h
@@ -21,7 +21,7 @@
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 * 23 *
24 * $OpenBSD: auth.h,v 1.20 2001/06/26 06:32:47 itojun Exp $ 24 * $OpenBSD: auth.h,v 1.21 2001/06/26 16:15:23 dugsong Exp $
25 */ 25 */
26#ifndef AUTH_H 26#ifndef AUTH_H
27#define AUTH_H 27#define AUTH_H
@@ -36,23 +36,36 @@
36#ifdef BSD_AUTH 36#ifdef BSD_AUTH
37#include <bsd_auth.h> 37#include <bsd_auth.h>
38#endif 38#endif
39#ifdef KRB5
40#include <krb5.h>
41#endif
39 42
40typedef struct Authctxt Authctxt; 43typedef struct Authctxt Authctxt;
41typedef struct KbdintDevice KbdintDevice; 44typedef struct KbdintDevice KbdintDevice;
42 45
43struct Authctxt { 46struct Authctxt {
44 int success; 47 int success;
45 int postponed; 48 int postponed;
46 int valid; 49 int valid;
47 int attempt; 50 int attempt;
48 int failures; 51 int failures;
49 char *user; 52 char *user;
50 char *service; 53 char *service;
51 struct passwd *pw; 54 struct passwd *pw;
52 char *style; 55 char *style;
53 void *kbdintctxt; 56 void *kbdintctxt;
54#ifdef BSD_AUTH 57#ifdef BSD_AUTH
55 auth_session_t *as; 58 auth_session_t *as;
59#endif
60#ifdef KRB4
61 char *krb4_ticket_file;
62#endif
63#ifdef KRB5
64 krb5_context krb5_ctx;
65 krb5_auth_context krb5_auth_ctx;
66 krb5_ccache krb5_fwd_ccache;
67 krb5_principal krb5_user;
68 char *krb5_ticket_file;
56#endif 69#endif
57}; 70};
58 71
@@ -125,21 +138,27 @@ int auth_rsa_challenge_dialog(RSA *);
125 * if the client could not be authenticated, and 1 if authentication was 138 * if the client could not be authenticated, and 1 if authentication was
126 * successful. This may exit if there is a serious protocol violation. 139 * successful. This may exit if there is a serious protocol violation.
127 */ 140 */
128int auth_krb4(const char *, KTEXT, char **); 141int auth_krb4(Authctxt *, KTEXT, char **);
129int krb4_init(uid_t); 142int auth_krb4_password(Authctxt *, const char *);
130void krb4_cleanup_proc(void *); 143void krb4_cleanup_proc(void *);
131int auth_krb4_password(struct passwd *, const char *);
132 144
133#ifdef AFS 145#ifdef AFS
134#include <kafs.h> 146#include <kafs.h>
135 147
136/* Accept passed Kerberos v4 ticket-granting ticket and AFS tokens. */ 148/* Accept passed Kerberos v4 ticket-granting ticket and AFS tokens. */
137int auth_kerberos_tgt(struct passwd *, const char *); 149int auth_krb4_tgt(Authctxt *, const char *);
138int auth_afs_token(struct passwd *, const char *); 150int auth_afs_token(Authctxt *, const char *);
139#endif /* AFS */ 151#endif /* AFS */
140 152
141#endif /* KRB4 */ 153#endif /* KRB4 */
142 154
155#ifdef KRB5
156int auth_krb5(Authctxt *authctxt, krb5_data *auth, char **client);
157int auth_krb5_tgt(Authctxt *authctxt, krb5_data *tgt);
158int auth_krb5_password(Authctxt *authctxt, const char *password);
159void krb5_cleanup_proc(void *authctxt);
160#endif /* KRB5 */
161
143#include "auth-pam.h" 162#include "auth-pam.h"
144#include "auth2-pam.h" 163#include "auth2-pam.h"
145 164
diff --git a/auth1.c b/auth1.c
index d5b7fa7c8..da2c23e52 100644
--- a/auth1.c
+++ b/auth1.c
@@ -10,7 +10,7 @@
10 */ 10 */
11 11
12#include "includes.h" 12#include "includes.h"
13RCSID("$OpenBSD: auth1.c,v 1.24 2001/06/23 15:12:17 itojun Exp $"); 13RCSID("$OpenBSD: auth1.c,v 1.25 2001/06/26 16:15:23 dugsong Exp $");
14 14
15#include "xmalloc.h" 15#include "xmalloc.h"
16#include "rsa.h" 16#include "rsa.h"
@@ -24,6 +24,7 @@ RCSID("$OpenBSD: auth1.c,v 1.24 2001/06/23 15:12:17 itojun Exp $");
24#include "auth.h" 24#include "auth.h"
25#include "session.h" 25#include "session.h"
26#include "misc.h" 26#include "misc.h"
27#include "uidswap.h"
27 28
28/* import */ 29/* import */
29extern ServerOptions options; 30extern ServerOptions options;
@@ -51,7 +52,7 @@ get_authname(int type)
51 case SSH_CMSG_AUTH_TIS: 52 case SSH_CMSG_AUTH_TIS:
52 case SSH_CMSG_AUTH_TIS_RESPONSE: 53 case SSH_CMSG_AUTH_TIS_RESPONSE:
53 return "challenge-response"; 54 return "challenge-response";
54#ifdef KRB4 55#if defined(KRB4) || defined(KRB5)
55 case SSH_CMSG_AUTH_KERBEROS: 56 case SSH_CMSG_AUTH_KERBEROS:
56 return "kerberos"; 57 return "kerberos";
57#endif 58#endif
@@ -84,7 +85,7 @@ do_authloop(Authctxt *authctxt)
84 85
85 /* If the user has no password, accept authentication immediately. */ 86 /* If the user has no password, accept authentication immediately. */
86 if (options.password_authentication && 87 if (options.password_authentication &&
87#ifdef KRB4 88#if defined(KRB4) || defined(KRB5)
88 (!options.kerberos_authentication || options.kerberos_or_local_passwd) && 89 (!options.kerberos_authentication || options.kerberos_or_local_passwd) &&
89#endif 90#endif
90#ifdef USE_PAM 91#ifdef USE_PAM
@@ -116,62 +117,64 @@ do_authloop(Authctxt *authctxt)
116 117
117 /* Process the packet. */ 118 /* Process the packet. */
118 switch (type) { 119 switch (type) {
119#ifdef AFS
120 case SSH_CMSG_HAVE_KERBEROS_TGT:
121 if (!options.kerberos_tgt_passing) {
122 verbose("Kerberos tgt passing disabled.");
123 break;
124 } else {
125 /* Accept Kerberos tgt. */
126 char *tgt = packet_get_string(&dlen);
127 packet_integrity_check(plen, 4 + dlen, type);
128 if (!auth_kerberos_tgt(pw, tgt))
129 verbose("Kerberos tgt REFUSED for %.100s", authctxt->user);
130 xfree(tgt);
131 }
132 continue;
133 120
134 case SSH_CMSG_HAVE_AFS_TOKEN: 121#if defined(KRB4) || defined(KRB5)
135 if (!options.afs_token_passing || !k_hasafs()) {
136 verbose("AFS token passing disabled.");
137 break;
138 } else {
139 /* Accept AFS token. */
140 char *token_string = packet_get_string(&dlen);
141 packet_integrity_check(plen, 4 + dlen, type);
142 if (!auth_afs_token(pw, token_string))
143 verbose("AFS token REFUSED for %.100s", authctxt->user);
144 xfree(token_string);
145 }
146 continue;
147#endif /* AFS */
148#ifdef KRB4
149 case SSH_CMSG_AUTH_KERBEROS: 122 case SSH_CMSG_AUTH_KERBEROS:
150 if (!options.kerberos_authentication) { 123 if (!options.kerberos_authentication) {
151 verbose("Kerberos authentication disabled."); 124 verbose("Kerberos authentication disabled.");
152 break;
153 } else { 125 } else {
154 /* Try Kerberos v4 authentication. */ 126 char *kdata = packet_get_string(&dlen);
155 KTEXT_ST auth; 127
156 char *tkt_user = NULL; 128 packet_integrity_check(plen, 4 + dlen, type);
157 char *kdata = packet_get_string((u_int *) &auth.length); 129
158 packet_integrity_check(plen, 4 + auth.length, type); 130 if (kdata[0] == 4) { /* KRB_PROT_VERSION */
159 131#ifdef KRB4
160 if (authctxt->valid) { 132 KTEXT_ST tkt;
161 if (auth.length < MAX_KTXT_LEN) 133
162 memcpy(auth.dat, kdata, auth.length); 134 tkt.length = dlen;
163 authenticated = auth_krb4(pw->pw_name, &auth, &tkt_user); 135 if (tkt.length < MAX_KTXT_LEN)
164 if (authenticated) { 136 memcpy(tkt.dat, kdata, tkt.length);
165 snprintf(info, sizeof info, 137
166 " tktuser %.100s", tkt_user); 138 if (auth_krb4(authctxt, &tkt, &client_user)) {
167 xfree(tkt_user); 139 authenticated = 1;
140 snprintf(info, sizeof(info),
141 " tktuser %.100s",
142 client_user);
143 xfree(client_user);
168 } 144 }
145#endif /* KRB4 */
146 } else {
147#ifdef KRB5
148 krb5_data tkt;
149 tkt.length = dlen;
150 tkt.data = kdata;
151
152 if (auth_krb5(authctxt, &tkt, &client_user)) {
153 authenticated = 1;
154 snprintf(info, sizeof(info),
155 " tktuser %.100s",
156 client_user);
157 xfree(client_user);
158 }
159#endif /* KRB5 */
169 } 160 }
170 xfree(kdata); 161 xfree(kdata);
171 } 162 }
172 break; 163 break;
173#endif /* KRB4 */ 164#endif /* KRB4 || KRB5 */
174 165
166#if defined(AFS) || defined(KRB5)
167 /* XXX - punt on backward compatibility here. */
168 case SSH_CMSG_HAVE_KERBEROS_TGT:
169 packet_send_debug("Kerberos TGT passing disabled before authentication.");
170 break;
171#ifdef AFS
172 case SSH_CMSG_HAVE_AFS_TOKEN:
173 packet_send_debug("AFS token passing disabled before authentication.");
174 break;
175#endif /* AFS */
176#endif /* AFS || KRB5 */
177
175 case SSH_CMSG_AUTH_RHOSTS: 178 case SSH_CMSG_AUTH_RHOSTS:
176 if (!options.rhosts_authentication) { 179 if (!options.rhosts_authentication) {
177 verbose("Rhosts authentication disabled."); 180 verbose("Rhosts authentication disabled.");
@@ -369,7 +372,7 @@ do_authentication()
369 struct passwd *pw; 372 struct passwd *pw;
370 int plen; 373 int plen;
371 u_int ulen; 374 u_int ulen;
372 char *user, *style = NULL; 375 char *p, *user, *style = NULL;
373 376
374 /* Get the name of the user that we wish to log in as. */ 377 /* Get the name of the user that we wish to log in as. */
375 packet_read_expect(&plen, SSH_CMSG_USER); 378 packet_read_expect(&plen, SSH_CMSG_USER);
@@ -379,8 +382,12 @@ do_authentication()
379 packet_integrity_check(plen, (4 + ulen), SSH_CMSG_USER); 382 packet_integrity_check(plen, (4 + ulen), SSH_CMSG_USER);
380 383
381 if ((style = strchr(user, ':')) != NULL) 384 if ((style = strchr(user, ':')) != NULL)
382 *style++ = 0; 385 *style++ = '\0';
383 386
387 /* XXX - SSH.com Kerberos v5 braindeath. */
388 if ((p = strchr(user, '@')) != NULL)
389 *p = '\0';
390
384 authctxt = authctxt_new(); 391 authctxt = authctxt_new();
385 authctxt->user = user; 392 authctxt->user = user;
386 authctxt->style = style; 393 authctxt->style = style;
diff --git a/readconf.c b/readconf.c
index 3c4d12662..4a1094685 100644
--- a/readconf.c
+++ b/readconf.c
@@ -12,7 +12,7 @@
12 */ 12 */
13 13
14#include "includes.h" 14#include "includes.h"
15RCSID("$OpenBSD: readconf.c,v 1.81 2001/06/23 02:34:30 markus Exp $"); 15RCSID("$OpenBSD: readconf.c,v 1.82 2001/06/26 16:15:23 dugsong Exp $");
16 16
17#include "ssh.h" 17#include "ssh.h"
18#include "xmalloc.h" 18#include "xmalloc.h"
@@ -96,11 +96,14 @@ typedef enum {
96 oForwardAgent, oForwardX11, oGatewayPorts, oRhostsAuthentication, 96 oForwardAgent, oForwardX11, oGatewayPorts, oRhostsAuthentication,
97 oPasswordAuthentication, oRSAAuthentication, oFallBackToRsh, oUseRsh, 97 oPasswordAuthentication, oRSAAuthentication, oFallBackToRsh, oUseRsh,
98 oChallengeResponseAuthentication, oXAuthLocation, 98 oChallengeResponseAuthentication, oXAuthLocation,
99#ifdef KRB4 99#if defined(KRB4) || defined(KRB5)
100 oKerberosAuthentication, 100 oKerberosAuthentication,
101#endif /* KRB4 */ 101#endif
102#if defined(AFS) || defined(KRB5)
103 oKerberosTgtPassing,
104#endif
102#ifdef AFS 105#ifdef AFS
103 oKerberosTgtPassing, oAFSTokenPassing, 106 oAFSTokenPassing,
104#endif 107#endif
105 oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward, 108 oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
106 oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand, 109 oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
@@ -137,11 +140,13 @@ static struct {
137 { "challengeresponseauthentication", oChallengeResponseAuthentication }, 140 { "challengeresponseauthentication", oChallengeResponseAuthentication },
138 { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */ 141 { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
139 { "tisauthentication", oChallengeResponseAuthentication }, /* alias */ 142 { "tisauthentication", oChallengeResponseAuthentication }, /* alias */
140#ifdef KRB4 143#if defined(KRB4) || defined(KRB5)
141 { "kerberosauthentication", oKerberosAuthentication }, 144 { "kerberosauthentication", oKerberosAuthentication },
142#endif /* KRB4 */ 145#endif
143#ifdef AFS 146#if defined(AFS) || defined(KRB5)
144 { "kerberostgtpassing", oKerberosTgtPassing }, 147 { "kerberostgtpassing", oKerberosTgtPassing },
148#endif
149#ifdef AFS
145 { "afstokenpassing", oAFSTokenPassing }, 150 { "afstokenpassing", oAFSTokenPassing },
146#endif 151#endif
147 { "fallbacktorsh", oFallBackToRsh }, 152 { "fallbacktorsh", oFallBackToRsh },
@@ -335,23 +340,21 @@ parse_flag:
335 case oChallengeResponseAuthentication: 340 case oChallengeResponseAuthentication:
336 intptr = &options->challenge_response_authentication; 341 intptr = &options->challenge_response_authentication;
337 goto parse_flag; 342 goto parse_flag;
338 343#if defined(KRB4) || defined(KRB5)
339#ifdef KRB4
340 case oKerberosAuthentication: 344 case oKerberosAuthentication:
341 intptr = &options->kerberos_authentication; 345 intptr = &options->kerberos_authentication;
342 goto parse_flag; 346 goto parse_flag;
343#endif /* KRB4 */ 347#endif
344 348#if defined(AFS) || defined(KRB5)
345#ifdef AFS
346 case oKerberosTgtPassing: 349 case oKerberosTgtPassing:
347 intptr = &options->kerberos_tgt_passing; 350 intptr = &options->kerberos_tgt_passing;
348 goto parse_flag; 351 goto parse_flag;
349 352#endif
353#ifdef AFS
350 case oAFSTokenPassing: 354 case oAFSTokenPassing:
351 intptr = &options->afs_token_passing; 355 intptr = &options->afs_token_passing;
352 goto parse_flag; 356 goto parse_flag;
353#endif 357#endif
354
355 case oFallBackToRsh: 358 case oFallBackToRsh:
356 intptr = &options->fallback_to_rsh; 359 intptr = &options->fallback_to_rsh;
357 goto parse_flag; 360 goto parse_flag;
@@ -724,11 +727,13 @@ initialize_options(Options * options)
724 options->rsa_authentication = -1; 727 options->rsa_authentication = -1;
725 options->pubkey_authentication = -1; 728 options->pubkey_authentication = -1;
726 options->challenge_response_authentication = -1; 729 options->challenge_response_authentication = -1;
727#ifdef KRB4 730#if defined(KRB4) || defined(KRB5)
728 options->kerberos_authentication = -1; 731 options->kerberos_authentication = -1;
729#endif 732#endif
730#ifdef AFS 733#if defined(AFS) || defined(KRB5)
731 options->kerberos_tgt_passing = -1; 734 options->kerberos_tgt_passing = -1;
735#endif
736#ifdef AFS
732 options->afs_token_passing = -1; 737 options->afs_token_passing = -1;
733#endif 738#endif
734 options->password_authentication = -1; 739 options->password_authentication = -1;
@@ -799,16 +804,18 @@ fill_default_options(Options * options)
799 options->pubkey_authentication = 1; 804 options->pubkey_authentication = 1;
800 if (options->challenge_response_authentication == -1) 805 if (options->challenge_response_authentication == -1)
801 options->challenge_response_authentication = 0; 806 options->challenge_response_authentication = 0;
802#ifdef KRB4 807#if defined(KRB4) || defined(KRB5)
803 if (options->kerberos_authentication == -1) 808 if (options->kerberos_authentication == -1)
804 options->kerberos_authentication = 1; 809 options->kerberos_authentication = 1;
805#endif /* KRB4 */ 810#endif
806#ifdef AFS 811#if defined(AFS) || defined(KRB5)
807 if (options->kerberos_tgt_passing == -1) 812 if (options->kerberos_tgt_passing == -1)
808 options->kerberos_tgt_passing = 1; 813 options->kerberos_tgt_passing = 1;
814#endif
815#ifdef AFS
809 if (options->afs_token_passing == -1) 816 if (options->afs_token_passing == -1)
810 options->afs_token_passing = 1; 817 options->afs_token_passing = 1;
811#endif /* AFS */ 818#endif
812 if (options->password_authentication == -1) 819 if (options->password_authentication == -1)
813 options->password_authentication = 1; 820 options->password_authentication = 1;
814 if (options->kbd_interactive_authentication == -1) 821 if (options->kbd_interactive_authentication == -1)
diff --git a/readconf.h b/readconf.h
index 4b3be7615..2f784e6e2 100644
--- a/readconf.h
+++ b/readconf.h
@@ -11,7 +11,7 @@
11 * called by a name other than "ssh" or "Secure Shell". 11 * called by a name other than "ssh" or "Secure Shell".
12 */ 12 */
13 13
14/* RCSID("$OpenBSD: readconf.h,v 1.33 2001/06/26 06:32:58 itojun Exp $"); */ 14/* RCSID("$OpenBSD: readconf.h,v 1.34 2001/06/26 16:15:24 dugsong Exp $"); */
15 15
16#ifndef READCONF_H 16#ifndef READCONF_H
17#define READCONF_H 17#define READCONF_H
@@ -41,12 +41,13 @@ typedef struct {
41 int hostbased_authentication; /* ssh2's rhosts_rsa */ 41 int hostbased_authentication; /* ssh2's rhosts_rsa */
42 int challenge_response_authentication; 42 int challenge_response_authentication;
43 /* Try S/Key or TIS, authentication. */ 43 /* Try S/Key or TIS, authentication. */
44#ifdef KRB4 44#if defined(KRB4) || defined(KRB5)
45 int kerberos_authentication; /* Try Kerberos 45 int kerberos_authentication; /* Try Kerberos authentication. */
46 * authentication. */ 46#endif
47#if defined(AFS) || defined(KRB5)
48 int kerberos_tgt_passing; /* Try Kerberos TGT passing. */
47#endif 49#endif
48#ifdef AFS 50#ifdef AFS
49 int kerberos_tgt_passing; /* Try Kerberos tgt passing. */
50 int afs_token_passing; /* Try AFS token passing. */ 51 int afs_token_passing; /* Try AFS token passing. */
51#endif 52#endif
52 int password_authentication; /* Try password 53 int password_authentication; /* Try password
diff --git a/servconf.c b/servconf.c
index 55b0b0039..7dbf31834 100644
--- a/servconf.c
+++ b/servconf.c
@@ -10,14 +10,11 @@
10 */ 10 */
11 11
12#include "includes.h" 12#include "includes.h"
13RCSID("$OpenBSD: servconf.c,v 1.84 2001/06/23 15:12:19 itojun Exp $"); 13RCSID("$OpenBSD: servconf.c,v 1.85 2001/06/26 16:15:24 dugsong Exp $");
14 14
15#ifdef KRB4 15#ifdef KRB4
16#include <krb.h> 16#include <krb.h>
17#endif 17#endif
18#ifdef AFS
19#include <kafs.h>
20#endif
21 18
22#include "ssh.h" 19#include "ssh.h"
23#include "log.h" 20#include "log.h"
@@ -70,13 +67,15 @@ initialize_server_options(ServerOptions *options)
70 options->hostbased_uses_name_from_packet_only = -1; 67 options->hostbased_uses_name_from_packet_only = -1;
71 options->rsa_authentication = -1; 68 options->rsa_authentication = -1;
72 options->pubkey_authentication = -1; 69 options->pubkey_authentication = -1;
73#ifdef KRB4 70#if defined(KRB4) || defined(KRB5)
74 options->kerberos_authentication = -1; 71 options->kerberos_authentication = -1;
75 options->kerberos_or_local_passwd = -1; 72 options->kerberos_or_local_passwd = -1;
76 options->kerberos_ticket_cleanup = -1; 73 options->kerberos_ticket_cleanup = -1;
77#endif 74#endif
78#ifdef AFS 75#if defined(AFS) || defined(KRB5)
79 options->kerberos_tgt_passing = -1; 76 options->kerberos_tgt_passing = -1;
77#endif
78#ifdef AFS
80 options->afs_token_passing = -1; 79 options->afs_token_passing = -1;
81#endif 80#endif
82 options->password_authentication = -1; 81 options->password_authentication = -1;
@@ -170,20 +169,22 @@ fill_default_server_options(ServerOptions *options)
170 options->rsa_authentication = 1; 169 options->rsa_authentication = 1;
171 if (options->pubkey_authentication == -1) 170 if (options->pubkey_authentication == -1)
172 options->pubkey_authentication = 1; 171 options->pubkey_authentication = 1;
173#ifdef KRB4 172#if defined(KRB4) || defined(KRB5)
174 if (options->kerberos_authentication == -1) 173 if (options->kerberos_authentication == -1)
175 options->kerberos_authentication = (access(KEYFILE, R_OK) == 0); 174 options->kerberos_authentication = (access(KEYFILE, R_OK) == 0);
176 if (options->kerberos_or_local_passwd == -1) 175 if (options->kerberos_or_local_passwd == -1)
177 options->kerberos_or_local_passwd = 1; 176 options->kerberos_or_local_passwd = 1;
178 if (options->kerberos_ticket_cleanup == -1) 177 if (options->kerberos_ticket_cleanup == -1)
179 options->kerberos_ticket_cleanup = 1; 178 options->kerberos_ticket_cleanup = 1;
180#endif /* KRB4 */ 179#endif
181#ifdef AFS 180#if defined(AFS) || defined(KRB5)
182 if (options->kerberos_tgt_passing == -1) 181 if (options->kerberos_tgt_passing == -1)
183 options->kerberos_tgt_passing = 0; 182 options->kerberos_tgt_passing = 0;
183#endif
184#ifdef AFS
184 if (options->afs_token_passing == -1) 185 if (options->afs_token_passing == -1)
185 options->afs_token_passing = k_hasafs(); 186 options->afs_token_passing = k_hasafs();
186#endif /* AFS */ 187#endif
187 if (options->password_authentication == -1) 188 if (options->password_authentication == -1)
188 options->password_authentication = 1; 189 options->password_authentication = 1;
189 if (options->kbd_interactive_authentication == -1) 190 if (options->kbd_interactive_authentication == -1)
@@ -224,11 +225,14 @@ typedef enum {
224 sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime, 225 sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
225 sPermitRootLogin, sLogFacility, sLogLevel, 226 sPermitRootLogin, sLogFacility, sLogLevel,
226 sRhostsAuthentication, sRhostsRSAAuthentication, sRSAAuthentication, 227 sRhostsAuthentication, sRhostsRSAAuthentication, sRSAAuthentication,
227#ifdef KRB4 228#if defined(KRB4) || defined(KRB5)
228 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, 229 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
229#endif 230#endif
231#if defined(AFS) || defined(KRB5)
232 sKerberosTgtPassing,
233#endif
230#ifdef AFS 234#ifdef AFS
231 sKerberosTgtPassing, sAFSTokenPassing, 235 sAFSTokenPassing,
232#endif 236#endif
233 sChallengeResponseAuthentication, 237 sChallengeResponseAuthentication,
234 sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress, 238 sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress,
@@ -267,13 +271,15 @@ static struct {
267 { "rsaauthentication", sRSAAuthentication }, 271 { "rsaauthentication", sRSAAuthentication },
268 { "pubkeyauthentication", sPubkeyAuthentication }, 272 { "pubkeyauthentication", sPubkeyAuthentication },
269 { "dsaauthentication", sPubkeyAuthentication }, /* alias */ 273 { "dsaauthentication", sPubkeyAuthentication }, /* alias */
270#ifdef KRB4 274#if defined(KRB4) || defined(KRB5)
271 { "kerberosauthentication", sKerberosAuthentication }, 275 { "kerberosauthentication", sKerberosAuthentication },
272 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd }, 276 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd },
273 { "kerberosticketcleanup", sKerberosTicketCleanup }, 277 { "kerberosticketcleanup", sKerberosTicketCleanup },
274#endif 278#endif
275#ifdef AFS 279#if defined(AFS) || defined(KRB5)
276 { "kerberostgtpassing", sKerberosTgtPassing }, 280 { "kerberostgtpassing", sKerberosTgtPassing },
281#endif
282#ifdef AFS
277 { "afstokenpassing", sAFSTokenPassing }, 283 { "afstokenpassing", sAFSTokenPassing },
278#endif 284#endif
279 { "passwordauthentication", sPasswordAuthentication }, 285 { "passwordauthentication", sPasswordAuthentication },
@@ -584,8 +590,7 @@ parse_flag:
584 case sPubkeyAuthentication: 590 case sPubkeyAuthentication:
585 intptr = &options->pubkey_authentication; 591 intptr = &options->pubkey_authentication;
586 goto parse_flag; 592 goto parse_flag;
587 593#if defined(KRB4) || defined(KRB5)
588#ifdef KRB4
589 case sKerberosAuthentication: 594 case sKerberosAuthentication:
590 intptr = &options->kerberos_authentication; 595 intptr = &options->kerberos_authentication;
591 goto parse_flag; 596 goto parse_flag;
@@ -598,12 +603,12 @@ parse_flag:
598 intptr = &options->kerberos_ticket_cleanup; 603 intptr = &options->kerberos_ticket_cleanup;
599 goto parse_flag; 604 goto parse_flag;
600#endif 605#endif
601 606#if defined(AFS) || defined(KRB5)
602#ifdef AFS
603 case sKerberosTgtPassing: 607 case sKerberosTgtPassing:
604 intptr = &options->kerberos_tgt_passing; 608 intptr = &options->kerberos_tgt_passing;
605 goto parse_flag; 609 goto parse_flag;
606 610#endif
611#ifdef AFS
607 case sAFSTokenPassing: 612 case sAFSTokenPassing:
608 intptr = &options->afs_token_passing; 613 intptr = &options->afs_token_passing;
609 goto parse_flag; 614 goto parse_flag;
diff --git a/servconf.h b/servconf.h
index a71b7c135..1b0220283 100644
--- a/servconf.h
+++ b/servconf.h
@@ -11,7 +11,7 @@
11 * called by a name other than "ssh" or "Secure Shell". 11 * called by a name other than "ssh" or "Secure Shell".
12 */ 12 */
13 13
14/* RCSID("$OpenBSD: servconf.h,v 1.45 2001/06/26 06:33:00 itojun Exp $"); */ 14/* RCSID("$OpenBSD: servconf.h,v 1.46 2001/06/26 16:15:24 dugsong Exp $"); */
15 15
16#ifndef SERVCONF_H 16#ifndef SERVCONF_H
17#define SERVCONF_H 17#define SERVCONF_H
@@ -73,7 +73,7 @@ typedef struct {
73 int hostbased_uses_name_from_packet_only; /* experimental */ 73 int hostbased_uses_name_from_packet_only; /* experimental */
74 int rsa_authentication; /* If true, permit RSA authentication. */ 74 int rsa_authentication; /* If true, permit RSA authentication. */
75 int pubkey_authentication; /* If true, permit ssh2 pubkey authentication. */ 75 int pubkey_authentication; /* If true, permit ssh2 pubkey authentication. */
76#ifdef KRB4 76#if defined(KRB4) || defined(KRB5)
77 int kerberos_authentication; /* If true, permit Kerberos 77 int kerberos_authentication; /* If true, permit Kerberos
78 * authentication. */ 78 * authentication. */
79 int kerberos_or_local_passwd; /* If true, permit kerberos 79 int kerberos_or_local_passwd; /* If true, permit kerberos
@@ -84,9 +84,11 @@ typedef struct {
84 int kerberos_ticket_cleanup; /* If true, destroy ticket 84 int kerberos_ticket_cleanup; /* If true, destroy ticket
85 * file on logout. */ 85 * file on logout. */
86#endif 86#endif
87#ifdef AFS 87#if defined(AFS) || defined(KRB5)
88 int kerberos_tgt_passing; /* If true, permit Kerberos tgt 88 int kerberos_tgt_passing; /* If true, permit Kerberos TGT
89 * passing. */ 89 * passing. */
90#endif
91#ifdef AFS
90 int afs_token_passing; /* If true, permit AFS token passing. */ 92 int afs_token_passing; /* If true, permit AFS token passing. */
91#endif 93#endif
92 int password_authentication; /* If true, permit password 94 int password_authentication; /* If true, permit password
diff --git a/session.c b/session.c
index 7d0e0723c..5a6afa7ec 100644
--- a/session.c
+++ b/session.c
@@ -33,7 +33,7 @@
33 */ 33 */
34 34
35#include "includes.h" 35#include "includes.h"
36RCSID("$OpenBSD: session.c,v 1.95 2001/06/25 08:25:39 markus Exp $"); 36RCSID("$OpenBSD: session.c,v 1.96 2001/06/26 16:15:24 dugsong Exp $");
37 37
38#include "ssh.h" 38#include "ssh.h"
39#include "ssh1.h" 39#include "ssh1.h"
@@ -99,7 +99,8 @@ typedef struct Session Session;
99struct Session { 99struct Session {
100 int used; 100 int used;
101 int self; 101 int self;
102 struct passwd *pw; 102 struct passwd *pw;
103 Authctxt *authctxt;
103 pid_t pid; 104 pid_t pid;
104 /* tty */ 105 /* tty */
105 char *term; 106 char *term;
@@ -198,6 +199,14 @@ do_authenticated(Authctxt *authctxt)
198 /* remove agent socket */ 199 /* remove agent socket */
199 if (auth_get_socket_name()) 200 if (auth_get_socket_name())
200 auth_sock_cleanup_proc(authctxt->pw); 201 auth_sock_cleanup_proc(authctxt->pw);
202#ifdef KRB4
203 if (options.kerberos_ticket_cleanup)
204 krb4_cleanup_proc(authctxt);
205#endif
206#ifdef KRB5
207 if (options.kerberos_ticket_cleanup)
208 krb5_cleanup_proc(authctxt);
209#endif
201} 210}
202 211
203/* 212/*
@@ -216,6 +225,7 @@ do_authenticated1(Authctxt *authctxt)
216 u_int proto_len, data_len, dlen; 225 u_int proto_len, data_len, dlen;
217 226
218 s = session_new(); 227 s = session_new();
228 s->authctxt = authctxt;
219 s->pw = authctxt->pw; 229 s->pw = authctxt->pw;
220 230
221 /* 231 /*
@@ -300,6 +310,58 @@ do_authenticated1(Authctxt *authctxt)
300 if (packet_set_maxsize(packet_get_int()) > 0) 310 if (packet_set_maxsize(packet_get_int()) > 0)
301 success = 1; 311 success = 1;
302 break; 312 break;
313
314#if defined(AFS) || defined(KRB5)
315 case SSH_CMSG_HAVE_KERBEROS_TGT:
316 if (!options.kerberos_tgt_passing) {
317 verbose("Kerberos TGT passing disabled.");
318 } else {
319 char *kdata = packet_get_string(&dlen);
320 packet_integrity_check(plen, 4 + dlen, type);
321
322 /* XXX - 0x41, see creds_to_radix version */
323 if (kdata[0] != 0x41) {
324#ifdef KRB5
325 krb5_data tgt;
326 tgt.data = kdata;
327 tgt.length = dlen;
328
329 if (auth_krb5_tgt(s->authctxt, &tgt))
330 success = 1;
331 else
332 verbose("Kerberos v5 TGT refused for %.100s", s->authctxt->user);
333#endif /* KRB5 */
334 } else {
335#ifdef AFS
336 if (auth_krb4_tgt(s->authctxt, kdata))
337 success = 1;
338 else
339 verbose("Kerberos v4 TGT refused for %.100s", s->authctxt->user);
340#endif /* AFS */
341 }
342 xfree(kdata);
343 }
344 break;
345#endif /* AFS || KRB5 */
346
347#ifdef AFS
348 case SSH_CMSG_HAVE_AFS_TOKEN:
349 if (!options.afs_token_passing || !k_hasafs()) {
350 verbose("AFS token passing disabled.");
351 } else {
352 /* Accept AFS token. */
353 char *token = packet_get_string(&dlen);
354 packet_integrity_check(plen, 4 + dlen, type);
355
356 if (auth_afs_token(s->authctxt, token))
357 success = 1;
358 else
359 verbose("AFS token refused for %.100s",
360 s->authctxt->user);
361 xfree(token);
362 }
363 break;
364#endif /* AFS */
303 365
304 case SSH_CMSG_EXEC_SHELL: 366 case SSH_CMSG_EXEC_SHELL:
305 case SSH_CMSG_EXEC_CMD: 367 case SSH_CMSG_EXEC_CMD:
@@ -615,7 +677,7 @@ static int
615check_quietlogin(Session *s, const char *command) 677check_quietlogin(Session *s, const char *command)
616{ 678{
617 char buf[256]; 679 char buf[256];
618 struct passwd * pw = s->pw; 680 struct passwd *pw = s->pw;
619 struct stat st; 681 struct stat st;
620 682
621 /* Return 1 if .hushlogin exists or a command given. */ 683 /* Return 1 if .hushlogin exists or a command given. */
@@ -955,7 +1017,7 @@ void
955do_child(Session *s, const char *command) 1017do_child(Session *s, const char *command)
956{ 1018{
957 const char *shell, *hostname = NULL, *cp = NULL; 1019 const char *shell, *hostname = NULL, *cp = NULL;
958 struct passwd * pw = s->pw; 1020 struct passwd *pw = s->pw;
959 char buf[256]; 1021 char buf[256];
960 char cmd[1024]; 1022 char cmd[1024];
961 FILE *f = NULL; 1023 FILE *f = NULL;
@@ -1134,10 +1196,10 @@ do_child(Session *s, const char *command)
1134 /* Try to get AFS tokens for the local cell. */ 1196 /* Try to get AFS tokens for the local cell. */
1135 if (k_hasafs()) { 1197 if (k_hasafs()) {
1136 char cell[64]; 1198 char cell[64];
1137 1199
1138 if (k_afs_cell_of_file(pw->pw_dir, cell, sizeof(cell)) == 0) 1200 if (k_afs_cell_of_file(pw->pw_dir, cell, sizeof(cell)) == 0)
1139 krb_afslog(cell, 0); 1201 krb_afslog(cell, 0);
1140 1202
1141 krb_afslog(0, 0); 1203 krb_afslog(0, 0);
1142 } 1204 }
1143#endif /* AFS */ 1205#endif /* AFS */
@@ -1221,16 +1283,16 @@ do_child(Session *s, const char *command)
1221 child_set_env(&env, &envsize, "KRB5CCNAME", cp); 1283 child_set_env(&env, &envsize, "KRB5CCNAME", cp);
1222 read_environment_file(&env, &envsize, "/etc/environment"); 1284 read_environment_file(&env, &envsize, "/etc/environment");
1223#endif 1285#endif
1224
1225#ifdef KRB4 1286#ifdef KRB4
1226 { 1287 if (s->authctxt->krb4_ticket_file)
1227 extern char *ticket; 1288 child_set_env(&env, &envsize, "KRBTKFILE",
1228 1289 s->authctxt->krb4_ticket_file);
1229 if (ticket) 1290#endif
1230 child_set_env(&env, &envsize, "KRBTKFILE", ticket); 1291#ifdef KRB5
1231 } 1292 if (s->authctxt->krb5_ticket_file)
1232#endif /* KRB4 */ 1293 child_set_env(&env, &envsize, "KRB5CCNAME",
1233 1294 s->authctxt->krb5_ticket_file);
1295#endif
1234#ifdef USE_PAM 1296#ifdef USE_PAM
1235 /* Pull in any environment variables that may have been set by PAM. */ 1297 /* Pull in any environment variables that may have been set by PAM. */
1236 do_pam_environment(&env, &envsize); 1298 do_pam_environment(&env, &envsize);
diff --git a/sshconnect1.c b/sshconnect1.c
index ec0a5c96c..09203d714 100644
--- a/sshconnect1.c
+++ b/sshconnect1.c
@@ -13,7 +13,7 @@
13 */ 13 */
14 14
15#include "includes.h" 15#include "includes.h"
16RCSID("$OpenBSD: sshconnect1.c,v 1.36 2001/06/23 22:37:46 markus Exp $"); 16RCSID("$OpenBSD: sshconnect1.c,v 1.37 2001/06/26 16:15:24 dugsong Exp $");
17 17
18#include <openssl/bn.h> 18#include <openssl/bn.h>
19#include <openssl/evp.h> 19#include <openssl/evp.h>
@@ -21,6 +21,9 @@ RCSID("$OpenBSD: sshconnect1.c,v 1.36 2001/06/23 22:37:46 markus Exp $");
21#ifdef KRB4 21#ifdef KRB4
22#include <krb.h> 22#include <krb.h>
23#endif 23#endif
24#ifdef KRB5
25#include <krb5.h>
26#endif
24#ifdef AFS 27#ifdef AFS
25#include <kafs.h> 28#include <kafs.h>
26#include "radix.h" 29#include "radix.h"
@@ -43,6 +46,7 @@ RCSID("$OpenBSD: sshconnect1.c,v 1.36 2001/06/23 22:37:46 markus Exp $");
43#include "readpass.h" 46#include "readpass.h"
44#include "cipher.h" 47#include "cipher.h"
45#include "canohost.h" 48#include "canohost.h"
49#include "auth.h"
46 50
47/* Session id for the current session. */ 51/* Session id for the current session. */
48u_char session_id[16]; 52u_char session_id[16];
@@ -379,7 +383,7 @@ try_rhosts_rsa_authentication(const char *local_user, Key * host_key)
379 383
380#ifdef KRB4 384#ifdef KRB4
381static int 385static int
382try_kerberos_authentication(void) 386try_krb4_authentication(void)
383{ 387{
384 KTEXT_ST auth; /* Kerberos data */ 388 KTEXT_ST auth; /* Kerberos data */
385 char *reply; 389 char *reply;
@@ -397,20 +401,21 @@ try_kerberos_authentication(void)
397 /* Don't do anything if we don't have any tickets. */ 401 /* Don't do anything if we don't have any tickets. */
398 if (stat(tkt_string(), &st) < 0) 402 if (stat(tkt_string(), &st) < 0)
399 return 0; 403 return 0;
400 404
401 strncpy(inst, (char *) krb_get_phost(get_canonical_hostname(1)), INST_SZ); 405 strlcpy(inst, (char *)krb_get_phost(get_canonical_hostname(1)),
402 406 INST_SZ);
403 realm = (char *) krb_realmofhost(get_canonical_hostname(1)); 407
408 realm = (char *)krb_realmofhost(get_canonical_hostname(1));
404 if (!realm) { 409 if (!realm) {
405 debug("Kerberos V4: no realm for %s", get_canonical_hostname(1)); 410 debug("Kerberos v4: no realm for %s", get_canonical_hostname(1));
406 return 0; 411 return 0;
407 } 412 }
408 /* This can really be anything. */ 413 /* This can really be anything. */
409 checksum = (u_long) getpid(); 414 checksum = (u_long)getpid();
410 415
411 r = krb_mk_req(&auth, KRB4_SERVICE_NAME, inst, realm, checksum); 416 r = krb_mk_req(&auth, KRB4_SERVICE_NAME, inst, realm, checksum);
412 if (r != KSUCCESS) { 417 if (r != KSUCCESS) {
413 debug("Kerberos V4 krb_mk_req failed: %s", krb_err_txt[r]); 418 debug("Kerberos v4 krb_mk_req failed: %s", krb_err_txt[r]);
414 return 0; 419 return 0;
415 } 420 }
416 /* Get session key to decrypt the server's reply with. */ 421 /* Get session key to decrypt the server's reply with. */
@@ -420,26 +425,26 @@ try_kerberos_authentication(void)
420 return 0; 425 return 0;
421 } 426 }
422 des_key_sched((des_cblock *) cred.session, schedule); 427 des_key_sched((des_cblock *) cred.session, schedule);
423 428
424 /* Send authentication info to server. */ 429 /* Send authentication info to server. */
425 packet_start(SSH_CMSG_AUTH_KERBEROS); 430 packet_start(SSH_CMSG_AUTH_KERBEROS);
426 packet_put_string((char *) auth.dat, auth.length); 431 packet_put_string((char *) auth.dat, auth.length);
427 packet_send(); 432 packet_send();
428 packet_write_wait(); 433 packet_write_wait();
429 434
430 /* Zero the buffer. */ 435 /* Zero the buffer. */
431 (void) memset(auth.dat, 0, MAX_KTXT_LEN); 436 (void) memset(auth.dat, 0, MAX_KTXT_LEN);
432 437
433 slen = sizeof(local); 438 slen = sizeof(local);
434 memset(&local, 0, sizeof(local)); 439 memset(&local, 0, sizeof(local));
435 if (getsockname(packet_get_connection_in(), 440 if (getsockname(packet_get_connection_in(),
436 (struct sockaddr *) & local, &slen) < 0) 441 (struct sockaddr *)&local, &slen) < 0)
437 debug("getsockname failed: %s", strerror(errno)); 442 debug("getsockname failed: %s", strerror(errno));
438 443
439 slen = sizeof(foreign); 444 slen = sizeof(foreign);
440 memset(&foreign, 0, sizeof(foreign)); 445 memset(&foreign, 0, sizeof(foreign));
441 if (getpeername(packet_get_connection_in(), 446 if (getpeername(packet_get_connection_in(),
442 (struct sockaddr *) & foreign, &slen) < 0) { 447 (struct sockaddr *)&foreign, &slen) < 0) {
443 debug("getpeername failed: %s", strerror(errno)); 448 debug("getpeername failed: %s", strerror(errno));
444 fatal_cleanup(); 449 fatal_cleanup();
445 } 450 }
@@ -448,96 +453,288 @@ try_kerberos_authentication(void)
448 switch (type) { 453 switch (type) {
449 case SSH_SMSG_FAILURE: 454 case SSH_SMSG_FAILURE:
450 /* Should really be SSH_SMSG_AUTH_KERBEROS_FAILURE */ 455 /* Should really be SSH_SMSG_AUTH_KERBEROS_FAILURE */
451 debug("Kerberos V4 authentication failed."); 456 debug("Kerberos v4 authentication failed.");
452 return 0; 457 return 0;
453 break; 458 break;
454 459
455 case SSH_SMSG_AUTH_KERBEROS_RESPONSE: 460 case SSH_SMSG_AUTH_KERBEROS_RESPONSE:
456 /* SSH_SMSG_AUTH_KERBEROS_SUCCESS */ 461 /* SSH_SMSG_AUTH_KERBEROS_SUCCESS */
457 debug("Kerberos V4 authentication accepted."); 462 debug("Kerberos v4 authentication accepted.");
458 463
459 /* Get server's response. */ 464 /* Get server's response. */
460 reply = packet_get_string((u_int *) &auth.length); 465 reply = packet_get_string((u_int *) &auth.length);
461 memcpy(auth.dat, reply, auth.length); 466 memcpy(auth.dat, reply, auth.length);
462 xfree(reply); 467 xfree(reply);
463 468
464 packet_integrity_check(plen, 4 + auth.length, type); 469 packet_integrity_check(plen, 4 + auth.length, type);
465 470
466 /* 471 /*
467 * If his response isn't properly encrypted with the session 472 * If his response isn't properly encrypted with the session
468 * key, and the decrypted checksum fails to match, he's 473 * key, and the decrypted checksum fails to match, he's
469 * bogus. Bail out. 474 * bogus. Bail out.
470 */ 475 */
471 r = krb_rd_priv(auth.dat, auth.length, schedule, &cred.session, 476 r = krb_rd_priv(auth.dat, auth.length, schedule, &cred.session,
472 &foreign, &local, &msg_data); 477 &foreign, &local, &msg_data);
473 if (r != KSUCCESS) { 478 if (r != KSUCCESS) {
474 debug("Kerberos V4 krb_rd_priv failed: %s", krb_err_txt[r]); 479 debug("Kerberos v4 krb_rd_priv failed: %s",
475 packet_disconnect("Kerberos V4 challenge failed!"); 480 krb_err_txt[r]);
481 packet_disconnect("Kerberos v4 challenge failed!");
476 } 482 }
477 /* Fetch the (incremented) checksum that we supplied in the request. */ 483 /* Fetch the (incremented) checksum that we supplied in the request. */
478 (void) memcpy((char *) &cksum, (char *) msg_data.app_data, sizeof(cksum)); 484 memcpy((char *)&cksum, (char *)msg_data.app_data,
485 sizeof(cksum));
479 cksum = ntohl(cksum); 486 cksum = ntohl(cksum);
480 487
481 /* If it matches, we're golden. */ 488 /* If it matches, we're golden. */
482 if (cksum == checksum + 1) { 489 if (cksum == checksum + 1) {
483 debug("Kerberos V4 challenge successful."); 490 debug("Kerberos v4 challenge successful.");
484 return 1; 491 return 1;
485 } else 492 } else
486 packet_disconnect("Kerberos V4 challenge failed!"); 493 packet_disconnect("Kerberos v4 challenge failed!");
487 break; 494 break;
488 495
489 default: 496 default:
490 packet_disconnect("Protocol error on Kerberos V4 response: %d", type); 497 packet_disconnect("Protocol error on Kerberos v4 response: %d", type);
491 } 498 }
492 return 0; 499 return 0;
493} 500}
494 501
495#endif /* KRB4 */ 502#endif /* KRB4 */
496 503
497#ifdef AFS 504#ifdef KRB5
498static int 505static int
499send_kerberos_tgt(void) 506try_krb5_authentication(krb5_context *context, krb5_auth_context *auth_context)
507{
508 krb5_error_code problem;
509 const char *tkfile;
510 struct stat buf;
511 krb5_ccache ccache = NULL;
512 const char *remotehost;
513 krb5_data ap;
514 int type, payload_len;
515 krb5_ap_rep_enc_part *reply = NULL;
516 int ret;
517
518 memset(&ap, 0, sizeof(ap));
519
520 problem = krb5_init_context(context);
521 if (problem) {
522 debug("Kerberos v5: krb5_init_context failed");
523 ret = 0;
524 goto out;
525 }
526
527 tkfile = krb5_cc_default_name(*context);
528 if (strncmp(tkfile, "FILE:", 5) == 0)
529 tkfile += 5;
530
531 if (stat(tkfile, &buf) == 0 && getuid() != buf.st_uid) {
532 debug("Kerberos v5: could not get default ccache (permission denied).");
533 ret = 0;
534 goto out;
535 }
536
537 problem = krb5_cc_default(*context, &ccache);
538 if (problem) {
539 debug("Kerberos v5: krb5_cc_default failed: %s",
540 krb5_get_err_text(*context, problem));
541 ret = 0;
542 goto out;
543 }
544
545 remotehost = get_canonical_hostname(1);
546
547 problem = krb5_mk_req(*context, auth_context, AP_OPTS_MUTUAL_REQUIRED,
548 "host", remotehost, NULL, ccache, &ap);
549 if (problem) {
550 debug("Kerberos v5: krb5_mk_req failed: %s",
551 krb5_get_err_text(*context, problem));
552 ret = 0;
553 goto out;
554 }
555
556 packet_start(SSH_CMSG_AUTH_KERBEROS);
557 packet_put_string((char *) ap.data, ap.length);
558 packet_send();
559 packet_write_wait();
560
561 xfree(ap.data);
562 ap.length = 0;
563
564 type = packet_read(&payload_len);
565 switch (type) {
566 case SSH_SMSG_FAILURE:
567 /* Should really be SSH_SMSG_AUTH_KERBEROS_FAILURE */
568 debug("Kerberos v5 authentication failed.");
569 ret = 0;
570 break;
571
572 case SSH_SMSG_AUTH_KERBEROS_RESPONSE:
573 /* SSH_SMSG_AUTH_KERBEROS_SUCCESS */
574 debug("Kerberos v5 authentication accepted.");
575
576 /* Get server's response. */
577 ap.data = packet_get_string((unsigned int *) &ap.length);
578
579 packet_integrity_check(payload_len, 4 + ap.length, type);
580 /* XXX je to dobre? */
581
582 problem = krb5_rd_rep(*context, *auth_context, &ap, &reply);
583 if (problem) {
584 ret = 0;
585 }
586 ret = 1;
587 break;
588
589 default:
590 packet_disconnect("Protocol error on Kerberos v5 response: %d",
591 type);
592 ret = 0;
593 break;
594
595 }
596
597 out:
598 if (ccache != NULL)
599 krb5_cc_close(*context, ccache);
600 if (reply != NULL)
601 krb5_free_ap_rep_enc_part(*context, reply);
602 if (ap.length > 0)
603 krb5_data_free(&ap);
604
605 return (ret);
606}
607
608static void
609send_krb5_tgt(krb5_context context, krb5_auth_context auth_context)
610{
611 int fd, type, payload_len;
612 krb5_error_code problem;
613 krb5_data outbuf;
614 krb5_ccache ccache = NULL;
615 krb5_creds creds;
616 krb5_kdc_flags flags;
617 const char *remotehost;
618
619 memset(&creds, 0, sizeof(creds));
620 memset(&outbuf, 0, sizeof(outbuf));
621
622 fd = packet_get_connection_in();
623
624 problem = krb5_auth_con_setaddrs_from_fd(context, auth_context, &fd);
625 if (problem)
626 goto out;
627
628 problem = krb5_cc_default(context, &ccache);
629 if (problem)
630 goto out;
631
632 problem = krb5_cc_get_principal(context, ccache, &creds.client);
633 if (problem)
634 goto out;
635
636 problem = krb5_build_principal(context, &creds.server,
637 strlen(creds.client->realm), creds.client->realm,
638 "krbtgt", creds.client->realm, NULL);
639 if (problem)
640 goto out;
641
642 creds.times.endtime = 0;
643
644 flags.i = 0;
645 flags.b.forwarded = 1;
646 flags.b.forwardable = krb5_config_get_bool(context, NULL,
647 "libdefaults", "forwardable", NULL);
648
649 remotehost = get_canonical_hostname(1);
650
651 problem = krb5_get_forwarded_creds(context, auth_context,
652 ccache, flags.i, remotehost, &creds, &outbuf);
653 if (problem)
654 goto out;
655
656 packet_start(SSH_CMSG_HAVE_KERBEROS_TGT);
657 packet_put_string((char *)outbuf.data, outbuf.length);
658 packet_send();
659 packet_write_wait();
660
661 type = packet_read(&payload_len);
662
663 if (type == SSH_SMSG_SUCCESS) {
664 char *pname;
665
666 krb5_unparse_name(context, creds.client, &pname);
667 debug("Kerberos v5 TGT forwarded (%s).", pname);
668 xfree(pname);
669 } else
670 debug("Kerberos v5 TGT forwarding failed.");
671
672 return;
673
674 out:
675 if (problem)
676 debug("Kerberos v5 TGT forwarding failed: %s",
677 krb5_get_err_text(context, problem));
678 if (creds.client)
679 krb5_free_principal(context, creds.client);
680 if (creds.server)
681 krb5_free_principal(context, creds.server);
682 if (ccache)
683 krb5_cc_close(context, ccache);
684 if (outbuf.data)
685 xfree(outbuf.data);
686}
687#endif /* KRB5 */
688
689#ifdef AFS
690static void
691send_krb4_tgt(void)
500{ 692{
501 CREDENTIALS *creds; 693 CREDENTIALS *creds;
502 char pname[ANAME_SZ], pinst[INST_SZ], prealm[REALM_SZ];
503 int r, type, plen;
504 char buffer[8192];
505 struct stat st; 694 struct stat st;
506 695 char buffer[4096], pname[ANAME_SZ], pinst[INST_SZ], prealm[REALM_SZ];
696 int problem, type, len;
697
507 /* Don't do anything if we don't have any tickets. */ 698 /* Don't do anything if we don't have any tickets. */
508 if (stat(tkt_string(), &st) < 0) 699 if (stat(tkt_string(), &st) < 0)
509 return 0; 700 return;
510 701
511 creds = xmalloc(sizeof(*creds)); 702 creds = xmalloc(sizeof(*creds));
512 703
513 if ((r = krb_get_tf_fullname(TKT_FILE, pname, pinst, prealm)) != KSUCCESS) { 704 problem = krb_get_tf_fullname(TKT_FILE, pname, pinst, prealm);
514 debug("Kerberos V4 tf_fullname failed: %s", krb_err_txt[r]); 705 if (problem)
515 return 0; 706 goto out;
516 } 707
517 if ((r = krb_get_cred("krbtgt", prealm, prealm, creds)) != GC_OK) { 708 problem = krb_get_cred("krbtgt", prealm, prealm, creds);
518 debug("Kerberos V4 get_cred failed: %s", krb_err_txt[r]); 709 if (problem)
519 return 0; 710 goto out;
520 } 711
521 if (time(0) > krb_life_to_time(creds->issue_date, creds->lifetime)) { 712 if (time(0) > krb_life_to_time(creds->issue_date, creds->lifetime)) {
522 debug("Kerberos V4 ticket expired: %s", TKT_FILE); 713 problem = RD_AP_EXP;
523 return 0; 714 goto out;
524 } 715 }
525 creds_to_radix(creds, (u_char *)buffer, sizeof buffer); 716 creds_to_radix(creds, (u_char *)buffer, sizeof(buffer));
526 xfree(creds); 717
527
528 packet_start(SSH_CMSG_HAVE_KERBEROS_TGT); 718 packet_start(SSH_CMSG_HAVE_KERBEROS_TGT);
529 packet_put_cstring(buffer); 719 packet_put_cstring(buffer);
530 packet_send(); 720 packet_send();
531 packet_write_wait(); 721 packet_write_wait();
532 722
533 type = packet_read(&plen); 723 type = packet_read(&len);
534 724
535 if (type == SSH_SMSG_FAILURE) 725 if (type == SSH_SMSG_SUCCESS)
536 debug("Kerberos TGT for realm %s rejected.", prealm); 726 debug("Kerberos v4 TGT forwarded (%s%s%s@%s).",
537 else if (type != SSH_SMSG_SUCCESS) 727 creds->pname, creds->pinst[0] ? "." : "",
538 packet_disconnect("Protocol error on Kerberos TGT response: %d", type); 728 creds->pinst, creds->realm);
539 729 else
540 return 1; 730 debug("Kerberos v4 TGT rejected.");
731
732 xfree(creds);
733 return;
734
735 out:
736 debug("Kerberos v4 TGT passing failed: %s", krb_err_txt[problem]);
737 xfree(creds);
541} 738}
542 739
543static void 740static void
@@ -546,10 +743,10 @@ send_afs_tokens(void)
546 CREDENTIALS creds; 743 CREDENTIALS creds;
547 struct ViceIoctl parms; 744 struct ViceIoctl parms;
548 struct ClearToken ct; 745 struct ClearToken ct;
549 int i, type, len, plen; 746 int i, type, len;
550 char buf[2048], *p, *server_cell; 747 char buf[2048], *p, *server_cell;
551 char buffer[8192]; 748 char buffer[8192];
552 749
553 /* Move over ktc_GetToken, here's something leaner. */ 750 /* Move over ktc_GetToken, here's something leaner. */
554 for (i = 0; i < 100; i++) { /* just in case */ 751 for (i = 0; i < 100; i++) { /* just in case */
555 parms.in = (char *) &i; 752 parms.in = (char *) &i;
@@ -559,7 +756,7 @@ send_afs_tokens(void)
559 if (k_pioctl(0, VIOCGETTOK, &parms, 0) != 0) 756 if (k_pioctl(0, VIOCGETTOK, &parms, 0) != 0)
560 break; 757 break;
561 p = buf; 758 p = buf;
562 759
563 /* Get secret token. */ 760 /* Get secret token. */
564 memcpy(&creds.ticket_st.length, p, sizeof(u_int)); 761 memcpy(&creds.ticket_st.length, p, sizeof(u_int));
565 if (creds.ticket_st.length > MAX_KTXT_LEN) 762 if (creds.ticket_st.length > MAX_KTXT_LEN)
@@ -567,7 +764,7 @@ send_afs_tokens(void)
567 p += sizeof(u_int); 764 p += sizeof(u_int);
568 memcpy(creds.ticket_st.dat, p, creds.ticket_st.length); 765 memcpy(creds.ticket_st.dat, p, creds.ticket_st.length);
569 p += creds.ticket_st.length; 766 p += creds.ticket_st.length;
570 767
571 /* Get clear token. */ 768 /* Get clear token. */
572 memcpy(&len, p, sizeof(len)); 769 memcpy(&len, p, sizeof(len));
573 if (len != sizeof(struct ClearToken)) 770 if (len != sizeof(struct ClearToken))
@@ -577,20 +774,22 @@ send_afs_tokens(void)
577 p += len; 774 p += len;
578 p += sizeof(len); /* primary flag */ 775 p += sizeof(len); /* primary flag */
579 server_cell = p; 776 server_cell = p;
580 777
581 /* Flesh out our credentials. */ 778 /* Flesh out our credentials. */
582 strlcpy(creds.service, "afs", sizeof creds.service); 779 strlcpy(creds.service, "afs", sizeof(creds.service));
583 creds.instance[0] = '\0'; 780 creds.instance[0] = '\0';
584 strlcpy(creds.realm, server_cell, REALM_SZ); 781 strlcpy(creds.realm, server_cell, REALM_SZ);
585 memcpy(creds.session, ct.HandShakeKey, DES_KEY_SZ); 782 memcpy(creds.session, ct.HandShakeKey, DES_KEY_SZ);
586 creds.issue_date = ct.BeginTimestamp; 783 creds.issue_date = ct.BeginTimestamp;
587 creds.lifetime = krb_time_to_life(creds.issue_date, ct.EndTimestamp); 784 creds.lifetime = krb_time_to_life(creds.issue_date,
785 ct.EndTimestamp);
588 creds.kvno = ct.AuthHandle; 786 creds.kvno = ct.AuthHandle;
589 snprintf(creds.pname, sizeof(creds.pname), "AFS ID %d", ct.ViceId); 787 snprintf(creds.pname, sizeof(creds.pname), "AFS ID %d", ct.ViceId);
590 creds.pinst[0] = '\0'; 788 creds.pinst[0] = '\0';
591 789
592 /* Encode token, ship it off. */ 790 /* Encode token, ship it off. */
593 if (creds_to_radix(&creds, (u_char *) buffer, sizeof buffer) <= 0) 791 if (creds_to_radix(&creds, (u_char *)buffer,
792 sizeof(buffer)) <= 0)
594 break; 793 break;
595 packet_start(SSH_CMSG_HAVE_AFS_TOKEN); 794 packet_start(SSH_CMSG_HAVE_AFS_TOKEN);
596 packet_put_cstring(buffer); 795 packet_put_cstring(buffer);
@@ -599,8 +798,8 @@ send_afs_tokens(void)
599 798
600 /* Roger, Roger. Clearance, Clarence. What's your vector, 799 /* Roger, Roger. Clearance, Clarence. What's your vector,
601 Victor? */ 800 Victor? */
602 type = packet_read(&plen); 801 type = packet_read(&len);
603 802
604 if (type == SSH_SMSG_FAILURE) 803 if (type == SSH_SMSG_FAILURE)
605 debug("AFS token for cell %s rejected.", server_cell); 804 debug("AFS token for cell %s rejected.", server_cell);
606 else if (type != SSH_SMSG_SUCCESS) 805 else if (type != SSH_SMSG_SUCCESS)
@@ -622,9 +821,9 @@ try_challenge_response_authentication(void)
622 u_int clen; 821 u_int clen;
623 char prompt[1024]; 822 char prompt[1024];
624 char *challenge, *response; 823 char *challenge, *response;
625 824
626 debug("Doing challenge reponse authentication."); 825 debug("Doing challenge reponse authentication.");
627 826
628 for (i = 0; i < options.number_of_password_prompts; i++) { 827 for (i = 0; i < options.number_of_password_prompts; i++) {
629 /* request a challenge */ 828 /* request a challenge */
630 packet_start(SSH_CMSG_AUTH_TIS); 829 packet_start(SSH_CMSG_AUTH_TIS);
@@ -913,9 +1112,13 @@ void
913ssh_userauth1(const char *local_user, const char *server_user, char *host, 1112ssh_userauth1(const char *local_user, const char *server_user, char *host,
914 Key **keys, int nkeys) 1113 Key **keys, int nkeys)
915{ 1114{
1115#ifdef KRB5
1116 krb5_context context = NULL;
1117 krb5_auth_context auth_context = NULL;
1118#endif
916 int i, type; 1119 int i, type;
917 int payload_len; 1120 int payload_len;
918 1121
919 if (supported_authentications == 0) 1122 if (supported_authentications == 0)
920 fatal("ssh_userauth1: server supports no auth methods"); 1123 fatal("ssh_userauth1: server supports no auth methods");
921 1124
@@ -934,43 +1137,40 @@ ssh_userauth1(const char *local_user, const char *server_user, char *host,
934 1137
935 /* check whether the connection was accepted without authentication. */ 1138 /* check whether the connection was accepted without authentication. */
936 if (type == SSH_SMSG_SUCCESS) 1139 if (type == SSH_SMSG_SUCCESS)
937 return; 1140 goto success;
938 if (type != SSH_SMSG_FAILURE) 1141 if (type != SSH_SMSG_FAILURE)
939 packet_disconnect("Protocol error: got %d in response to SSH_CMSG_USER", 1142 packet_disconnect("Protocol error: got %d in response to SSH_CMSG_USER", type);
940 type); 1143
941 1144#ifdef KRB5
942#ifdef AFS 1145 if ((supported_authentications & (1 << SSH_AUTH_KERBEROS)) &&
943 /* Try Kerberos tgt passing if the server supports it. */ 1146 options.kerberos_authentication) {
944 if ((supported_authentications & (1 << SSH_PASS_KERBEROS_TGT)) && 1147 debug("Trying Kerberos v5 authentication.");
945 options.kerberos_tgt_passing) { 1148
946 if (options.cipher == SSH_CIPHER_NONE) 1149 if (try_krb5_authentication(&context, &auth_context)) {
947 log("WARNING: Encryption is disabled! Ticket will be transmitted in the clear!"); 1150 type = packet_read(&payload_len);
948 (void) send_kerberos_tgt(); 1151 if (type == SSH_SMSG_SUCCESS)
949 } 1152 goto success;
950 /* Try AFS token passing if the server supports it. */ 1153 if (type != SSH_SMSG_FAILURE)
951 if ((supported_authentications & (1 << SSH_PASS_AFS_TOKEN)) && 1154 packet_disconnect("Protocol error: got %d in response to Kerberos v5 auth", type);
952 options.afs_token_passing && k_hasafs()) { 1155 }
953 if (options.cipher == SSH_CIPHER_NONE)
954 log("WARNING: Encryption is disabled! Token will be transmitted in the clear!");
955 send_afs_tokens();
956 } 1156 }
957#endif /* AFS */ 1157#endif /* KRB5 */
958 1158
959#ifdef KRB4 1159#ifdef KRB4
960 if ((supported_authentications & (1 << SSH_AUTH_KERBEROS)) && 1160 if ((supported_authentications & (1 << SSH_AUTH_KERBEROS)) &&
961 options.kerberos_authentication) { 1161 options.kerberos_authentication) {
962 debug("Trying Kerberos authentication."); 1162 debug("Trying Kerberos v4 authentication.");
963 if (try_kerberos_authentication()) { 1163
964 /* The server should respond with success or failure. */ 1164 if (try_krb4_authentication()) {
965 type = packet_read(&payload_len); 1165 type = packet_read(&payload_len);
966 if (type == SSH_SMSG_SUCCESS) 1166 if (type == SSH_SMSG_SUCCESS)
967 return; 1167 goto success;
968 if (type != SSH_SMSG_FAILURE) 1168 if (type != SSH_SMSG_FAILURE)
969 packet_disconnect("Protocol error: got %d in response to Kerberos auth", type); 1169 packet_disconnect("Protocol error: got %d in response to Kerberos v4 auth", type);
970 } 1170 }
971 } 1171 }
972#endif /* KRB4 */ 1172#endif /* KRB4 */
973 1173
974 /* 1174 /*
975 * Use rhosts authentication if running in privileged socket and we 1175 * Use rhosts authentication if running in privileged socket and we
976 * do not wish to remain anonymous. 1176 * do not wish to remain anonymous.
@@ -986,7 +1186,7 @@ ssh_userauth1(const char *local_user, const char *server_user, char *host,
986 /* The server should respond with success or failure. */ 1186 /* The server should respond with success or failure. */
987 type = packet_read(&payload_len); 1187 type = packet_read(&payload_len);
988 if (type == SSH_SMSG_SUCCESS) 1188 if (type == SSH_SMSG_SUCCESS)
989 return; 1189 goto success;
990 if (type != SSH_SMSG_FAILURE) 1190 if (type != SSH_SMSG_FAILURE)
991 packet_disconnect("Protocol error: got %d in response to rhosts auth", 1191 packet_disconnect("Protocol error: got %d in response to rhosts auth",
992 type); 1192 type);
@@ -1000,7 +1200,7 @@ ssh_userauth1(const char *local_user, const char *server_user, char *host,
1000 for (i = 0; i < nkeys; i++) { 1200 for (i = 0; i < nkeys; i++) {
1001 if (keys[i] != NULL && keys[i]->type == KEY_RSA1 && 1201 if (keys[i] != NULL && keys[i]->type == KEY_RSA1 &&
1002 try_rhosts_rsa_authentication(local_user, keys[i])) 1202 try_rhosts_rsa_authentication(local_user, keys[i]))
1003 return; 1203 goto success;
1004 } 1204 }
1005 } 1205 }
1006 /* Try RSA authentication if the server supports it. */ 1206 /* Try RSA authentication if the server supports it. */
@@ -1012,20 +1212,20 @@ ssh_userauth1(const char *local_user, const char *server_user, char *host,
1012 * it, whereas identity files may require passphrases. 1212 * it, whereas identity files may require passphrases.
1013 */ 1213 */
1014 if (try_agent_authentication()) 1214 if (try_agent_authentication())
1015 return; 1215 goto success;
1016 1216
1017 /* Try RSA authentication for each identity. */ 1217 /* Try RSA authentication for each identity. */
1018 for (i = 0; i < options.num_identity_files; i++) 1218 for (i = 0; i < options.num_identity_files; i++)
1019 if (options.identity_keys[i] != NULL && 1219 if (options.identity_keys[i] != NULL &&
1020 options.identity_keys[i]->type == KEY_RSA1 && 1220 options.identity_keys[i]->type == KEY_RSA1 &&
1021 try_rsa_authentication(options.identity_files[i])) 1221 try_rsa_authentication(options.identity_files[i]))
1022 return; 1222 goto success;
1023 } 1223 }
1024 /* Try challenge response authentication if the server supports it. */ 1224 /* Try challenge response authentication if the server supports it. */
1025 if ((supported_authentications & (1 << SSH_AUTH_TIS)) && 1225 if ((supported_authentications & (1 << SSH_AUTH_TIS)) &&
1026 options.challenge_response_authentication && !options.batch_mode) { 1226 options.challenge_response_authentication && !options.batch_mode) {
1027 if (try_challenge_response_authentication()) 1227 if (try_challenge_response_authentication())
1028 return; 1228 goto success;
1029 } 1229 }
1030 /* Try password authentication if the server supports it. */ 1230 /* Try password authentication if the server supports it. */
1031 if ((supported_authentications & (1 << SSH_AUTH_PASSWORD)) && 1231 if ((supported_authentications & (1 << SSH_AUTH_PASSWORD)) &&
@@ -1035,9 +1235,41 @@ ssh_userauth1(const char *local_user, const char *server_user, char *host,
1035 snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password: ", 1235 snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password: ",
1036 server_user, host); 1236 server_user, host);
1037 if (try_password_authentication(prompt)) 1237 if (try_password_authentication(prompt))
1038 return; 1238 goto success;
1039 } 1239 }
1040 /* All authentication methods have failed. Exit with an error message. */ 1240 /* All authentication methods have failed. Exit with an error message. */
1041 fatal("Permission denied."); 1241 fatal("Permission denied.");
1042 /* NOTREACHED */ 1242 /* NOTREACHED */
1243
1244 success:
1245#ifdef KRB5
1246 /* Try Kerberos v5 TGT passing. */
1247 if ((supported_authentications & (1 << SSH_PASS_KERBEROS_TGT)) &&
1248 options.kerberos_tgt_passing && context && auth_context) {
1249 if (options.cipher == SSH_CIPHER_NONE)
1250 log("WARNING: Encryption is disabled! Ticket will be transmitted in the clear!");
1251 send_krb5_tgt(context, auth_context);
1252 }
1253 if (auth_context)
1254 krb5_auth_con_free(context, auth_context);
1255 if (context)
1256 krb5_free_context(context);
1257#endif
1258
1259#ifdef AFS
1260 /* Try Kerberos v4 TGT passing if the server supports it. */
1261 if ((supported_authentications & (1 << SSH_PASS_KERBEROS_TGT)) &&
1262 options.kerberos_tgt_passing) {
1263 if (options.cipher == SSH_CIPHER_NONE)
1264 log("WARNING: Encryption is disabled! Ticket will be transmitted in the clear!");
1265 send_krb4_tgt();
1266 }
1267 /* Try AFS token passing if the server supports it. */
1268 if ((supported_authentications & (1 << SSH_PASS_AFS_TOKEN)) &&
1269 options.afs_token_passing && k_hasafs()) {
1270 if (options.cipher == SSH_CIPHER_NONE)
1271 log("WARNING: Encryption is disabled! Token will be transmitted in the clear!");
1272 send_afs_tokens();
1273 }
1274#endif /* AFS */
1043} 1275}
diff --git a/sshd.c b/sshd.c
index 936e861a9..dd5d7ab2c 100644
--- a/sshd.c
+++ b/sshd.c
@@ -40,7 +40,7 @@
40 */ 40 */
41 41
42#include "includes.h" 42#include "includes.h"
43RCSID("$OpenBSD: sshd.c,v 1.201 2001/06/23 19:12:43 markus Exp $"); 43RCSID("$OpenBSD: sshd.c,v 1.202 2001/06/26 16:15:25 dugsong Exp $");
44 44
45#include <openssl/dh.h> 45#include <openssl/dh.h>
46#include <openssl/bn.h> 46#include <openssl/bn.h>
@@ -1160,13 +1160,13 @@ main(int ac, char **av)
1160 "originating port not trusted."); 1160 "originating port not trusted.");
1161 options.rhosts_authentication = 0; 1161 options.rhosts_authentication = 0;
1162 } 1162 }
1163#ifdef KRB4 1163#if defined(KRB4) && !defined(KRB5)
1164 if (!packet_connection_is_ipv4() && 1164 if (!packet_connection_is_ipv4() &&
1165 options.kerberos_authentication) { 1165 options.kerberos_authentication) {
1166 debug("Kerberos Authentication disabled, only available for IPv4."); 1166 debug("Kerberos Authentication disabled, only available for IPv4.");
1167 options.kerberos_authentication = 0; 1167 options.kerberos_authentication = 0;
1168 } 1168 }
1169#endif /* KRB4 */ 1169#endif /* KRB4 && !KRB5 */
1170#ifdef AFS 1170#ifdef AFS
1171 /* If machine has AFS, set process authentication group. */ 1171 /* If machine has AFS, set process authentication group. */
1172 if (k_hasafs()) { 1172 if (k_hasafs()) {
@@ -1186,13 +1186,6 @@ main(int ac, char **av)
1186 do_ssh1_kex(); 1186 do_ssh1_kex();
1187 do_authentication(); 1187 do_authentication();
1188 } 1188 }
1189
1190#ifdef KRB4
1191 /* Cleanup user's ticket cache file. */
1192 if (options.kerberos_ticket_cleanup)
1193 (void) dest_tkt();
1194#endif /* KRB4 */
1195
1196 /* The connection has been terminated. */ 1189 /* The connection has been terminated. */
1197 verbose("Closing connection to %.100s", remote_ip); 1190 verbose("Closing connection to %.100s", remote_ip);
1198 1191
@@ -1268,13 +1261,15 @@ do_ssh1_kex(void)
1268 auth_mask |= 1 << SSH_AUTH_RHOSTS_RSA; 1261 auth_mask |= 1 << SSH_AUTH_RHOSTS_RSA;
1269 if (options.rsa_authentication) 1262 if (options.rsa_authentication)
1270 auth_mask |= 1 << SSH_AUTH_RSA; 1263 auth_mask |= 1 << SSH_AUTH_RSA;
1271#ifdef KRB4 1264#if defined(KRB4) || defined(KRB5)
1272 if (options.kerberos_authentication) 1265 if (options.kerberos_authentication)
1273 auth_mask |= 1 << SSH_AUTH_KERBEROS; 1266 auth_mask |= 1 << SSH_AUTH_KERBEROS;
1274#endif 1267#endif
1275#ifdef AFS 1268#if defined(AFS) || defined(KRB5)
1276 if (options.kerberos_tgt_passing) 1269 if (options.kerberos_tgt_passing)
1277 auth_mask |= 1 << SSH_PASS_KERBEROS_TGT; 1270 auth_mask |= 1 << SSH_PASS_KERBEROS_TGT;
1271#endif
1272#ifdef AFS
1278 if (options.afs_token_passing) 1273 if (options.afs_token_passing)
1279 auth_mask |= 1 << SSH_PASS_AFS_TOKEN; 1274 auth_mask |= 1 << SSH_PASS_AFS_TOKEN;
1280#endif 1275#endif