]> andersk Git - gssapi-openssh.git/blob - openssh/sshconnect1.c
initial checkin of Bin He's support for GSI authentication in protocol 1,
[gssapi-openssh.git] / openssh / sshconnect1.c
1 /*
2  * Author: Tatu Ylonen <ylo@cs.hut.fi>
3  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
4  *                    All rights reserved
5  * Code to connect to a remote host, and to perform the client side of the
6  * login (authentication) dialog.
7  *
8  * As far as I am concerned, the code I have written for this software
9  * can be used freely for any purpose.  Any derived versions of this
10  * software must be clearly marked as such, and if the derived work is
11  * incompatible with the protocol description in the RFC file, it must be
12  * called by a name other than "ssh" or "Secure Shell".
13  */
14
15 #include "includes.h"
16 RCSID("$OpenBSD: sshconnect1.c,v 1.41 2001/10/06 11:18:19 markus Exp $");
17
18 #include <openssl/bn.h>
19 #include <openssl/evp.h>
20
21 #ifdef KRB4
22 #include <krb.h>
23 #endif
24 #ifdef KRB5
25 #include <krb5.h>
26 #ifndef HEIMDAL
27 #define krb5_get_err_text(context,code) error_message(code)
28 #endif /* !HEIMDAL */
29 #endif
30 #ifdef AFS
31 #include <kafs.h>
32 #include "radix.h"
33 #endif
34
35 #include "ssh.h"
36 #include "ssh1.h"
37 #include "xmalloc.h"
38 #include "rsa.h"
39 #include "buffer.h"
40 #include "packet.h"
41 #include "mpaux.h"
42 #include "uidswap.h"
43 #include "log.h"
44 #include "readconf.h"
45 #include "key.h"
46 #include "authfd.h"
47 #include "sshconnect.h"
48 #include "authfile.h"
49 #include "readpass.h"
50 #include "cipher.h"
51 #include "canohost.h"
52 #include "auth.h"
53
54 /*modified by binhe*/
55 #ifdef GSSAPI
56 #include <gssapi.h>
57 #include <openssl/md5.h>
58 #include "bufaux.h"
59 static char gssapi_patch_version[] = GSSAPI_PATCH_VERSION;
60 /*
61  * MD5 hash of host and session keys for verification. This is filled
62  * in in ssh_login() and then checked in try_gssapi_authentication().
63  */
64 unsigned char ssh_key_digest[16];
65 #endif /* GSSAPI */
66 /*end of modification*/
67
68 /* Session id for the current session. */
69 u_char session_id[16];
70 u_int supported_authentications = 0;
71
72 extern Options options;
73 extern char *__progname;
74
75 /*
76  * Checks if the user has an authentication agent, and if so, tries to
77  * authenticate using the agent.
78  */
79 static int
80 try_agent_authentication(void)
81 {
82         int type;
83         char *comment;
84         AuthenticationConnection *auth;
85         u_char response[16];
86         u_int i;
87         int plen, clen;
88         Key *key;
89         BIGNUM *challenge;
90
91         /* Get connection to the agent. */
92         auth = ssh_get_authentication_connection();
93         if (!auth)
94                 return 0;
95
96         challenge = BN_new();
97
98         /* Loop through identities served by the agent. */
99         for (key = ssh_get_first_identity(auth, &comment, 1);
100              key != NULL;
101              key = ssh_get_next_identity(auth, &comment, 1)) {
102
103                 /* Try this identity. */
104                 debug("Trying RSA authentication via agent with '%.100s'", comment);
105                 xfree(comment);
106
107                 /* Tell the server that we are willing to authenticate using this key. */
108                 packet_start(SSH_CMSG_AUTH_RSA);
109                 packet_put_bignum(key->rsa->n);
110                 packet_send();
111                 packet_write_wait();
112
113                 /* Wait for server's response. */
114                 type = packet_read(&plen);
115
116                 /* The server sends failure if it doesn\'t like our key or
117                    does not support RSA authentication. */
118                 if (type == SSH_SMSG_FAILURE) {
119                         debug("Server refused our key.");
120                         key_free(key);
121                         continue;
122                 }
123                 /* Otherwise it should have sent a challenge. */
124                 if (type != SSH_SMSG_AUTH_RSA_CHALLENGE)
125                         packet_disconnect("Protocol error during RSA authentication: %d",
126                                           type);
127
128                 packet_get_bignum(challenge, &clen);
129
130                 packet_integrity_check(plen, clen, type);
131
132                 debug("Received RSA challenge from server.");
133
134                 /* Ask the agent to decrypt the challenge. */
135                 if (!ssh_decrypt_challenge(auth, key, challenge, session_id, 1, response)) {
136                         /*
137                          * The agent failed to authenticate this identifier
138                          * although it advertised it supports this.  Just
139                          * return a wrong value.
140                          */
141                         log("Authentication agent failed to decrypt challenge.");
142                         memset(response, 0, sizeof(response));
143                 }
144                 key_free(key);
145                 debug("Sending response to RSA challenge.");
146
147                 /* Send the decrypted challenge back to the server. */
148                 packet_start(SSH_CMSG_AUTH_RSA_RESPONSE);
149                 for (i = 0; i < 16; i++)
150                         packet_put_char(response[i]);
151                 packet_send();
152                 packet_write_wait();
153
154                 /* Wait for response from the server. */
155                 type = packet_read(&plen);
156
157                 /* The server returns success if it accepted the authentication. */
158                 if (type == SSH_SMSG_SUCCESS) {
159                         ssh_close_authentication_connection(auth);
160                         BN_clear_free(challenge);
161                         debug("RSA authentication accepted by server.");
162                         return 1;
163                 }
164                 /* Otherwise it should return failure. */
165                 if (type != SSH_SMSG_FAILURE)
166                         packet_disconnect("Protocol error waiting RSA auth response: %d",
167                                           type);
168         }
169         ssh_close_authentication_connection(auth);
170         BN_clear_free(challenge);
171         debug("RSA authentication using agent refused.");
172         return 0;
173 }
174
175 /*
176  * Computes the proper response to a RSA challenge, and sends the response to
177  * the server.
178  */
179 static void
180 respond_to_rsa_challenge(BIGNUM * challenge, RSA * prv)
181 {
182         u_char buf[32], response[16];
183         MD5_CTX md;
184         int i, len;
185
186         /* Decrypt the challenge using the private key. */
187         /* XXX think about Bleichenbacher, too */
188         if (rsa_private_decrypt(challenge, challenge, prv) <= 0)
189                 packet_disconnect(
190                     "respond_to_rsa_challenge: rsa_private_decrypt failed");
191
192         /* Compute the response. */
193         /* The response is MD5 of decrypted challenge plus session id. */
194         len = BN_num_bytes(challenge);
195         if (len <= 0 || len > sizeof(buf))
196                 packet_disconnect(
197                     "respond_to_rsa_challenge: bad challenge length %d", len);
198
199         memset(buf, 0, sizeof(buf));
200         BN_bn2bin(challenge, buf + sizeof(buf) - len);
201         MD5_Init(&md);
202         MD5_Update(&md, buf, 32);
203         MD5_Update(&md, session_id, 16);
204         MD5_Final(response, &md);
205
206         debug("Sending response to host key RSA challenge.");
207
208         /* Send the response back to the server. */
209         packet_start(SSH_CMSG_AUTH_RSA_RESPONSE);
210         for (i = 0; i < 16; i++)
211                 packet_put_char(response[i]);
212         packet_send();
213         packet_write_wait();
214
215         memset(buf, 0, sizeof(buf));
216         memset(response, 0, sizeof(response));
217         memset(&md, 0, sizeof(md));
218 }
219
220 /*
221  * Checks if the user has authentication file, and if so, tries to authenticate
222  * the user using it.
223  */
224 static int
225 try_rsa_authentication(int idx)
226 {
227         BIGNUM *challenge;
228         Key *public, *private;
229         char buf[300], *passphrase, *comment, *authfile;
230         int i, type, quit, plen, clen;
231
232         public = options.identity_keys[idx];
233         authfile = options.identity_files[idx];
234         comment = xstrdup(authfile);
235
236         debug("Trying RSA authentication with key '%.100s'", comment);
237
238         /* Tell the server that we are willing to authenticate using this key. */
239         packet_start(SSH_CMSG_AUTH_RSA);
240         packet_put_bignum(public->rsa->n);
241         packet_send();
242         packet_write_wait();
243
244         /* Wait for server's response. */
245         type = packet_read(&plen);
246
247         /*
248          * The server responds with failure if it doesn\'t like our key or
249          * doesn\'t support RSA authentication.
250          */
251         if (type == SSH_SMSG_FAILURE) {
252                 debug("Server refused our key.");
253                 xfree(comment);
254                 return 0;
255         }
256         /* Otherwise, the server should respond with a challenge. */
257         if (type != SSH_SMSG_AUTH_RSA_CHALLENGE)
258                 packet_disconnect("Protocol error during RSA authentication: %d", type);
259
260         /* Get the challenge from the packet. */
261         challenge = BN_new();
262         packet_get_bignum(challenge, &clen);
263
264         packet_integrity_check(plen, clen, type);
265
266         debug("Received RSA challenge from server.");
267
268         /*
269          * If the key is not stored in external hardware, we have to
270          * load the private key.  Try first with empty passphrase; if it
271          * fails, ask for a passphrase.
272          */
273         if (public->flags && KEY_FLAG_EXT)
274                 private = public;
275         else
276                 private = key_load_private_type(KEY_RSA1, authfile, "", NULL);
277         if (private == NULL && !options.batch_mode) {
278                 snprintf(buf, sizeof(buf),
279                     "Enter passphrase for RSA key '%.100s': ", comment);
280                 for (i = 0; i < options.number_of_password_prompts; i++) {
281                         passphrase = read_passphrase(buf, 0);
282                         if (strcmp(passphrase, "") != 0) {
283                                 private = key_load_private_type(KEY_RSA1,
284                                     authfile, passphrase, NULL);
285                                 quit = 0;
286                         } else {
287                                 debug2("no passphrase given, try next key");
288                                 quit = 1;
289                         }
290                         memset(passphrase, 0, strlen(passphrase));
291                         xfree(passphrase);
292                         if (private != NULL || quit)
293                                 break;
294                         debug2("bad passphrase given, try again...");
295                 }
296         }
297         /* We no longer need the comment. */
298         xfree(comment);
299
300         if (private == NULL) {
301                 if (!options.batch_mode)
302                         error("Bad passphrase.");
303
304                 /* Send a dummy response packet to avoid protocol error. */
305                 packet_start(SSH_CMSG_AUTH_RSA_RESPONSE);
306                 for (i = 0; i < 16; i++)
307                         packet_put_char(0);
308                 packet_send();
309                 packet_write_wait();
310
311                 /* Expect the server to reject it... */
312                 packet_read_expect(&plen, SSH_SMSG_FAILURE);
313                 BN_clear_free(challenge);
314                 return 0;
315         }
316
317         /* Compute and send a response to the challenge. */
318         respond_to_rsa_challenge(challenge, private->rsa);
319
320         /* Destroy the private key unless it in external hardware. */
321         if (!(private->flags & KEY_FLAG_EXT))
322                 key_free(private);
323
324         /* We no longer need the challenge. */
325         BN_clear_free(challenge);
326
327         /* Wait for response from the server. */
328         type = packet_read(&plen);
329         if (type == SSH_SMSG_SUCCESS) {
330                 debug("RSA authentication accepted by server.");
331                 return 1;
332         }
333         if (type != SSH_SMSG_FAILURE)
334                 packet_disconnect("Protocol error waiting RSA auth response: %d", type);
335         debug("RSA authentication refused.");
336         return 0;
337 }
338
339 /*
340  * Tries to authenticate the user using combined rhosts or /etc/hosts.equiv
341  * authentication and RSA host authentication.
342  */
343 static int
344 try_rhosts_rsa_authentication(const char *local_user, Key * host_key)
345 {
346         int type;
347         BIGNUM *challenge;
348         int plen, clen;
349
350         debug("Trying rhosts or /etc/hosts.equiv with RSA host authentication.");
351
352         /* Tell the server that we are willing to authenticate using this key. */
353         packet_start(SSH_CMSG_AUTH_RHOSTS_RSA);
354         packet_put_cstring(local_user);
355         packet_put_int(BN_num_bits(host_key->rsa->n));
356         packet_put_bignum(host_key->rsa->e);
357         packet_put_bignum(host_key->rsa->n);
358         packet_send();
359         packet_write_wait();
360
361         /* Wait for server's response. */
362         type = packet_read(&plen);
363
364         /* The server responds with failure if it doesn't admit our
365            .rhosts authentication or doesn't know our host key. */
366         if (type == SSH_SMSG_FAILURE) {
367                 debug("Server refused our rhosts authentication or host key.");
368                 return 0;
369         }
370         /* Otherwise, the server should respond with a challenge. */
371         if (type != SSH_SMSG_AUTH_RSA_CHALLENGE)
372                 packet_disconnect("Protocol error during RSA authentication: %d", type);
373
374         /* Get the challenge from the packet. */
375         challenge = BN_new();
376         packet_get_bignum(challenge, &clen);
377
378         packet_integrity_check(plen, clen, type);
379
380         debug("Received RSA challenge for host key from server.");
381
382         /* Compute a response to the challenge. */
383         respond_to_rsa_challenge(challenge, host_key->rsa);
384
385         /* We no longer need the challenge. */
386         BN_clear_free(challenge);
387
388         /* Wait for response from the server. */
389         type = packet_read(&plen);
390         if (type == SSH_SMSG_SUCCESS) {
391                 debug("Rhosts or /etc/hosts.equiv with RSA host authentication accepted by server.");
392                 return 1;
393         }
394         if (type != SSH_SMSG_FAILURE)
395                 packet_disconnect("Protocol error waiting RSA auth response: %d", type);
396         debug("Rhosts or /etc/hosts.equiv with RSA host authentication refused.");
397         return 0;
398 }
399
400 #ifdef KRB4
401 static int
402 try_krb4_authentication(void)
403 {
404         KTEXT_ST auth;          /* Kerberos data */
405         char *reply;
406         char inst[INST_SZ];
407         char *realm;
408         CREDENTIALS cred;
409         int r, type, plen;
410         socklen_t slen;
411         Key_schedule schedule;
412         u_long checksum, cksum;
413         MSG_DAT msg_data;
414         struct sockaddr_in local, foreign;
415         struct stat st;
416
417         /* Don't do anything if we don't have any tickets. */
418         if (stat(tkt_string(), &st) < 0)
419                 return 0;
420         
421         strlcpy(inst, (char *)krb_get_phost(get_canonical_hostname(1)),
422             INST_SZ);
423         
424         realm = (char *)krb_realmofhost(get_canonical_hostname(1));
425         if (!realm) {
426                 debug("Kerberos v4: no realm for %s", get_canonical_hostname(1));
427                 return 0;
428         }
429         /* This can really be anything. */
430         checksum = (u_long)getpid();
431         
432         r = krb_mk_req(&auth, KRB4_SERVICE_NAME, inst, realm, checksum);
433         if (r != KSUCCESS) {
434                 debug("Kerberos v4 krb_mk_req failed: %s", krb_err_txt[r]);
435                 return 0;
436         }
437         /* Get session key to decrypt the server's reply with. */
438         r = krb_get_cred(KRB4_SERVICE_NAME, inst, realm, &cred);
439         if (r != KSUCCESS) {
440                 debug("get_cred failed: %s", krb_err_txt[r]);
441                 return 0;
442         }
443         des_key_sched((des_cblock *) cred.session, schedule);
444         
445         /* Send authentication info to server. */
446         packet_start(SSH_CMSG_AUTH_KERBEROS);
447         packet_put_string((char *) auth.dat, auth.length);
448         packet_send();
449         packet_write_wait();
450         
451         /* Zero the buffer. */
452         (void) memset(auth.dat, 0, MAX_KTXT_LEN);
453         
454         slen = sizeof(local);
455         memset(&local, 0, sizeof(local));
456         if (getsockname(packet_get_connection_in(),
457             (struct sockaddr *)&local, &slen) < 0)
458                 debug("getsockname failed: %s", strerror(errno));
459         
460         slen = sizeof(foreign);
461         memset(&foreign, 0, sizeof(foreign));
462         if (getpeername(packet_get_connection_in(),
463             (struct sockaddr *)&foreign, &slen) < 0) {
464                 debug("getpeername failed: %s", strerror(errno));
465                 fatal_cleanup();
466         }
467         /* Get server reply. */
468         type = packet_read(&plen);
469         switch (type) {
470         case SSH_SMSG_FAILURE:
471                 /* Should really be SSH_SMSG_AUTH_KERBEROS_FAILURE */
472                 debug("Kerberos v4 authentication failed.");
473                 return 0;
474                 break;
475                 
476         case SSH_SMSG_AUTH_KERBEROS_RESPONSE:
477                 /* SSH_SMSG_AUTH_KERBEROS_SUCCESS */
478                 debug("Kerberos v4 authentication accepted.");
479                 
480                 /* Get server's response. */
481                 reply = packet_get_string((u_int *) &auth.length);
482                 memcpy(auth.dat, reply, auth.length);
483                 xfree(reply);
484                 
485                 packet_integrity_check(plen, 4 + auth.length, type);
486                 
487                 /*
488                  * If his response isn't properly encrypted with the session
489                  * key, and the decrypted checksum fails to match, he's
490                  * bogus. Bail out.
491                  */
492                 r = krb_rd_priv(auth.dat, auth.length, schedule, &cred.session,
493                     &foreign, &local, &msg_data);
494                 if (r != KSUCCESS) {
495                         debug("Kerberos v4 krb_rd_priv failed: %s",
496                             krb_err_txt[r]);
497                         packet_disconnect("Kerberos v4 challenge failed!");
498                 }
499                 /* Fetch the (incremented) checksum that we supplied in the request. */
500                 memcpy((char *)&cksum, (char *)msg_data.app_data,
501                     sizeof(cksum));
502                 cksum = ntohl(cksum);
503                 
504                 /* If it matches, we're golden. */
505                 if (cksum == checksum + 1) {
506                         debug("Kerberos v4 challenge successful.");
507                         return 1;
508                 } else
509                         packet_disconnect("Kerberos v4 challenge failed!");
510                 break;
511                 
512         default:
513                 packet_disconnect("Protocol error on Kerberos v4 response: %d", type);
514         }
515         return 0;
516 }
517
518 #endif /* KRB4 */
519
520 #ifdef KRB5
521 static int
522 try_krb5_authentication(krb5_context *context, krb5_auth_context *auth_context)
523 {
524         krb5_error_code problem;
525         const char *tkfile;
526         struct stat buf;
527         krb5_ccache ccache = NULL;
528         const char *remotehost;
529         krb5_data ap;
530         int type, payload_len;
531         krb5_ap_rep_enc_part *reply = NULL;
532         int ret;
533         
534         memset(&ap, 0, sizeof(ap));
535         
536         problem = krb5_init_context(context);
537         if (problem) {
538                 debug("Kerberos v5: krb5_init_context failed");
539                 ret = 0;
540                 goto out;
541         }
542         
543         problem = krb5_auth_con_init(*context, auth_context);
544         if (problem) {
545                 debug("Kerberos v5: krb5_auth_con_init failed");
546                 ret = 0;
547                 goto out;
548         }
549
550 #ifndef HEIMDAL 
551         problem = krb5_auth_con_setflags(*context, *auth_context,
552                                          KRB5_AUTH_CONTEXT_RET_TIME);
553         if (problem) {
554                 debug("Kerberos v5: krb5_auth_con_setflags failed");
555                 ret = 0;
556                 goto out;
557         }                                
558 #endif
559
560         tkfile = krb5_cc_default_name(*context);
561         if (strncmp(tkfile, "FILE:", 5) == 0)
562                 tkfile += 5;
563         
564         if (stat(tkfile, &buf) == 0 && getuid() != buf.st_uid) {
565                 debug("Kerberos v5: could not get default ccache (permission denied).");
566                 ret = 0;
567                 goto out;
568         }
569         
570         problem = krb5_cc_default(*context, &ccache);
571         if (problem) {
572                 debug("Kerberos v5: krb5_cc_default failed: %s",
573                     krb5_get_err_text(*context, problem));
574                 ret = 0;
575                 goto out;
576         }
577         
578         remotehost = get_canonical_hostname(1);
579         
580         problem = krb5_mk_req(*context, auth_context, AP_OPTS_MUTUAL_REQUIRED,
581             "host", remotehost, NULL, ccache, &ap);
582         if (problem) {
583                 debug("Kerberos v5: krb5_mk_req failed: %s",
584                     krb5_get_err_text(*context, problem));
585                 ret = 0;
586                 goto out;
587         }
588         
589         packet_start(SSH_CMSG_AUTH_KERBEROS);
590         packet_put_string((char *) ap.data, ap.length);
591         packet_send();
592         packet_write_wait();
593         
594         xfree(ap.data);
595         ap.length = 0;
596         
597         type = packet_read(&payload_len);
598         switch (type) {
599         case SSH_SMSG_FAILURE:
600                 /* Should really be SSH_SMSG_AUTH_KERBEROS_FAILURE */
601                 debug("Kerberos v5 authentication failed.");
602                 ret = 0;
603                 break;
604                 
605         case SSH_SMSG_AUTH_KERBEROS_RESPONSE:
606                 /* SSH_SMSG_AUTH_KERBEROS_SUCCESS */
607                 debug("Kerberos v5 authentication accepted.");
608                 
609                 /* Get server's response. */
610                 ap.data = packet_get_string((unsigned int *) &ap.length);
611                 
612                 packet_integrity_check(payload_len, 4 + ap.length, type);
613                 /* XXX je to dobre? */
614                 
615                 problem = krb5_rd_rep(*context, *auth_context, &ap, &reply);
616                 if (problem) {
617                         ret = 0;
618                 }
619                 ret = 1;
620                 break;
621                 
622         default:
623                 packet_disconnect("Protocol error on Kerberos v5 response: %d",
624                     type);
625                 ret = 0;
626                 break;
627                 
628         }
629         
630  out:
631         if (ccache != NULL)
632                 krb5_cc_close(*context, ccache);
633         if (reply != NULL)
634                 krb5_free_ap_rep_enc_part(*context, reply);
635         if (ap.length > 0)
636 #ifdef HEIMDAL
637                 krb5_data_free(&ap);
638 #else
639                 xfree(ap.data);
640 #endif  
641         
642         return (ret);
643 }
644
645 static void
646 send_krb5_tgt(krb5_context context, krb5_auth_context auth_context)
647 {
648         int fd, type, payload_len;
649         krb5_error_code problem;
650         krb5_data outbuf;
651         krb5_ccache ccache = NULL;
652         krb5_creds creds;
653 #ifdef HEIMDAL
654         krb5_kdc_flags flags;
655 #else
656         int forwardable;
657 #endif
658         const char *remotehost;
659         
660         memset(&creds, 0, sizeof(creds));
661         memset(&outbuf, 0, sizeof(outbuf));
662         
663         fd = packet_get_connection_in();
664         
665 #ifdef HEIMDAL  
666         problem = krb5_auth_con_setaddrs_from_fd(context, auth_context, &fd);
667         if (problem)
668                 goto out;
669 #else
670         problem = krb5_auth_con_genaddrs(context, auth_context, fd,
671                         KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR |
672                         KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR);
673         if (problem) {
674                 debug("krb5_auth_con_genaddrs: %.100s", error_message(problem));
675                 goto out;
676         }
677 #endif
678         
679         problem = krb5_cc_default(context, &ccache);
680         if (problem)
681                 goto out;
682         
683         problem = krb5_cc_get_principal(context, ccache, &creds.client);
684         if (problem)
685                 goto out;
686         
687 #ifdef HEIMDAL
688         problem = krb5_build_principal(context, &creds.server,
689             strlen(creds.client->realm), creds.client->realm,
690             "krbtgt", creds.client->realm, NULL);
691 #else
692         problem = krb5_build_principal(context, &creds.server,
693             creds.client->realm.length, creds.client->realm.data,
694             "krbtgt", creds.client->realm.data, NULL);
695 #endif
696
697         if (problem)
698                 goto out;
699         
700         creds.times.endtime = 0;
701         
702 #ifdef HEIMDAL  
703         flags.i = 0;
704         flags.b.forwarded = 1;
705         flags.b.forwardable = krb5_config_get_bool(context,  NULL,
706             "libdefaults", "forwardable", NULL);
707         
708         remotehost = get_canonical_hostname(1);
709         
710         problem = krb5_get_forwarded_creds(context, auth_context,
711             ccache, flags.i, remotehost, &creds, &outbuf);
712         if (problem)
713                 goto out;
714 #else
715         forwardable = 1;
716
717         remotehost = get_canonical_hostname(1);
718
719         problem = krb5_fwd_tgt_creds (context, auth_context, 
720             remotehost, creds.client, creds.server, ccache, forwardable,
721             &outbuf);
722         if (problem)
723                 goto out;
724 #endif
725         
726         packet_start(SSH_CMSG_HAVE_KERBEROS_TGT);
727         packet_put_string((char *)outbuf.data, outbuf.length);
728         packet_send();
729         packet_write_wait();
730         
731         type = packet_read(&payload_len);
732         
733         if (type == SSH_SMSG_SUCCESS) {
734                 char *pname;
735                 
736                 krb5_unparse_name(context, creds.client, &pname);
737                 debug("Kerberos v5 TGT forwarded (%s).", pname);
738                 xfree(pname);
739         } else
740                 debug("Kerberos v5 TGT forwarding failed.");
741         
742         return;
743         
744  out:
745         if (problem)
746                 debug("Kerberos v5 TGT forwarding failed: %s",
747                     krb5_get_err_text(context, problem));
748         if (creds.client)
749                 krb5_free_principal(context, creds.client);
750         if (creds.server)
751                 krb5_free_principal(context, creds.server);
752         if (ccache)
753                 krb5_cc_close(context, ccache);
754         if (outbuf.data)
755                 xfree(outbuf.data);
756 }
757 #endif /* KRB5 */
758
759 #ifdef AFS
760 static void
761 send_krb4_tgt(void)
762 {
763         CREDENTIALS *creds;
764         struct stat st;
765         char buffer[4096], pname[ANAME_SZ], pinst[INST_SZ], prealm[REALM_SZ];
766         int problem, type, len;
767         
768         /* Don't do anything if we don't have any tickets. */
769         if (stat(tkt_string(), &st) < 0)
770                 return;
771         
772         creds = xmalloc(sizeof(*creds));
773         
774         problem = krb_get_tf_fullname(TKT_FILE, pname, pinst, prealm);
775         if (problem)
776                 goto out;
777         
778         problem = krb_get_cred("krbtgt", prealm, prealm, creds);
779         if (problem)
780                 goto out;
781         
782         if (time(0) > krb_life_to_time(creds->issue_date, creds->lifetime)) {
783                 problem = RD_AP_EXP;
784                 goto out;
785         }
786         creds_to_radix(creds, (u_char *)buffer, sizeof(buffer));
787         
788         packet_start(SSH_CMSG_HAVE_KERBEROS_TGT);
789         packet_put_cstring(buffer);
790         packet_send();
791         packet_write_wait();
792         
793         type = packet_read(&len);
794         
795         if (type == SSH_SMSG_SUCCESS)
796                 debug("Kerberos v4 TGT forwarded (%s%s%s@%s).",
797                     creds->pname, creds->pinst[0] ? "." : "",
798                     creds->pinst, creds->realm);
799         else
800                 debug("Kerberos v4 TGT rejected.");
801         
802         xfree(creds);
803         return;
804         
805  out:
806         debug("Kerberos v4 TGT passing failed: %s", krb_err_txt[problem]);
807         xfree(creds);
808 }
809
810 static void
811 send_afs_tokens(void)
812 {
813         CREDENTIALS creds;
814         struct ViceIoctl parms;
815         struct ClearToken ct;
816         int i, type, len;
817         char buf[2048], *p, *server_cell;
818         char buffer[8192];
819         
820         /* Move over ktc_GetToken, here's something leaner. */
821         for (i = 0; i < 100; i++) {     /* just in case */
822                 parms.in = (char *) &i;
823                 parms.in_size = sizeof(i);
824                 parms.out = buf;
825                 parms.out_size = sizeof(buf);
826                 if (k_pioctl(0, VIOCGETTOK, &parms, 0) != 0)
827                         break;
828                 p = buf;
829                 
830                 /* Get secret token. */
831                 memcpy(&creds.ticket_st.length, p, sizeof(u_int));
832                 if (creds.ticket_st.length > MAX_KTXT_LEN)
833                         break;
834                 p += sizeof(u_int);
835                 memcpy(creds.ticket_st.dat, p, creds.ticket_st.length);
836                 p += creds.ticket_st.length;
837                 
838                 /* Get clear token. */
839                 memcpy(&len, p, sizeof(len));
840                 if (len != sizeof(struct ClearToken))
841                         break;
842                 p += sizeof(len);
843                 memcpy(&ct, p, len);
844                 p += len;
845                 p += sizeof(len);       /* primary flag */
846                 server_cell = p;
847                 
848                 /* Flesh out our credentials. */
849                 strlcpy(creds.service, "afs", sizeof(creds.service));
850                 creds.instance[0] = '\0';
851                 strlcpy(creds.realm, server_cell, REALM_SZ);
852                 memcpy(creds.session, ct.HandShakeKey, DES_KEY_SZ);
853                 creds.issue_date = ct.BeginTimestamp;
854                 creds.lifetime = krb_time_to_life(creds.issue_date,
855                     ct.EndTimestamp);
856                 creds.kvno = ct.AuthHandle;
857                 snprintf(creds.pname, sizeof(creds.pname), "AFS ID %d", ct.ViceId);
858                 creds.pinst[0] = '\0';
859                 
860                 /* Encode token, ship it off. */
861                 if (creds_to_radix(&creds, (u_char *)buffer,
862                     sizeof(buffer)) <= 0)
863                         break;
864                 packet_start(SSH_CMSG_HAVE_AFS_TOKEN);
865                 packet_put_cstring(buffer);
866                 packet_send();
867                 packet_write_wait();
868
869                 /* Roger, Roger. Clearance, Clarence. What's your vector,
870                    Victor? */
871                 type = packet_read(&len);
872                 
873                 if (type == SSH_SMSG_FAILURE)
874                         debug("AFS token for cell %s rejected.", server_cell);
875                 else if (type != SSH_SMSG_SUCCESS)
876                         packet_disconnect("Protocol error on AFS token response: %d", type);
877         }
878 }
879
880 #endif /* AFS */
881
882 /*
883  * Tries to authenticate with any string-based challenge/response system.
884  * Note that the client code is not tied to s/key or TIS.
885  */
886 static int
887 try_challenge_response_authentication(void)
888 {
889         int type, i;
890         int payload_len;
891         u_int clen;
892         char prompt[1024];
893         char *challenge, *response;
894
895         debug("Doing challenge response authentication.");
896
897         for (i = 0; i < options.number_of_password_prompts; i++) {
898                 /* request a challenge */
899                 packet_start(SSH_CMSG_AUTH_TIS);
900                 packet_send();
901                 packet_write_wait();
902
903                 type = packet_read(&payload_len);
904                 if (type != SSH_SMSG_FAILURE &&
905                     type != SSH_SMSG_AUTH_TIS_CHALLENGE) {
906                         packet_disconnect("Protocol error: got %d in response "
907                             "to SSH_CMSG_AUTH_TIS", type);
908                 }
909                 if (type != SSH_SMSG_AUTH_TIS_CHALLENGE) {
910                         debug("No challenge.");
911                         return 0;
912                 }
913                 challenge = packet_get_string(&clen);
914                 packet_integrity_check(payload_len, (4 + clen), type);
915                 snprintf(prompt, sizeof prompt, "%s%s", challenge,
916                      strchr(challenge, '\n') ? "" : "\nResponse: ");
917                 xfree(challenge);
918                 if (i != 0)
919                         error("Permission denied, please try again.");
920                 if (options.cipher == SSH_CIPHER_NONE)
921                         log("WARNING: Encryption is disabled! "
922                             "Reponse will be transmitted in clear text.");
923                 response = read_passphrase(prompt, 0);
924                 if (strcmp(response, "") == 0) {
925                         xfree(response);
926                         break;
927                 }
928                 packet_start(SSH_CMSG_AUTH_TIS_RESPONSE);
929                 ssh_put_password(response);
930                 memset(response, 0, strlen(response));
931                 xfree(response);
932                 packet_send();
933                 packet_write_wait();
934                 type = packet_read(&payload_len);
935                 if (type == SSH_SMSG_SUCCESS)
936                         return 1;
937                 if (type != SSH_SMSG_FAILURE)
938                         packet_disconnect("Protocol error: got %d in response "
939                             "to SSH_CMSG_AUTH_TIS_RESPONSE", type);
940         }
941         /* failure */
942         return 0;
943 }
944
945 /*
946  * Tries to authenticate with plain passwd authentication.
947  */
948 static int
949 try_password_authentication(char *prompt)
950 {
951         int type, i, payload_len;
952         char *password;
953
954         debug("Doing password authentication.");
955         if (options.cipher == SSH_CIPHER_NONE)
956                 log("WARNING: Encryption is disabled! Password will be transmitted in clear text.");
957         for (i = 0; i < options.number_of_password_prompts; i++) {
958                 if (i != 0)
959                         error("Permission denied, please try again.");
960                 password = read_passphrase(prompt, 0);
961                 packet_start(SSH_CMSG_AUTH_PASSWORD);
962                 ssh_put_password(password);
963                 memset(password, 0, strlen(password));
964                 xfree(password);
965                 packet_send();
966                 packet_write_wait();
967
968                 type = packet_read(&payload_len);
969                 if (type == SSH_SMSG_SUCCESS)
970                         return 1;
971                 if (type != SSH_SMSG_FAILURE)
972                         packet_disconnect("Protocol error: got %d in response to passwd auth", type);
973         }
974         /* failure */
975         return 0;
976 }
977
978 /*modified by binhe*/
979 #ifdef GSSAPI
980 /*
981  * This code stolen from the gss-client.c sample program from MIT's
982  * kerberos 5 distribution.
983  */
984
985 gss_cred_id_t gss_cred = GSS_C_NO_CREDENTIAL;
986
987 static void display_status_1(m, code, type)
988  char *m;
989  OM_uint32 code;
990  int type;
991 {
992   OM_uint32 maj_stat, min_stat;
993   gss_buffer_desc msg;
994   OM_uint32 msg_ctx;
995
996   msg_ctx = 0;
997   while (1) {
998     maj_stat = gss_display_status(&min_stat, code,
999                                   type, GSS_C_NULL_OID,
1000                                   &msg_ctx, &msg);
1001     debug("GSS-API error %s: %s", m, (char *)msg.value);
1002     (void) gss_release_buffer(&min_stat, &msg);
1003
1004     if (!msg_ctx)
1005       break;
1006   }
1007 }
1008
1009 static void display_gssapi_status(msg, maj_stat, min_stat)
1010   char *msg;
1011   OM_uint32 maj_stat;
1012   OM_uint32 min_stat;
1013 {
1014   display_status_1(msg, maj_stat, GSS_C_GSS_CODE);
1015   display_status_1(msg, min_stat, GSS_C_MECH_CODE);
1016 }
1017
1018 #ifdef GSI
1019 int get_gssapi_cred()
1020 {
1021   OM_uint32 maj_stat;
1022   OM_uint32 min_stat;
1023
1024
1025   debug("calling gss_acquire_cred");
1026   maj_stat = gss_acquire_cred(&min_stat,
1027                               GSS_C_NO_NAME,
1028                               GSS_C_INDEFINITE,
1029                               GSS_C_NO_OID_SET,
1030                               GSS_C_INITIATE,
1031                               &gss_cred,
1032                               NULL,
1033                               NULL);
1034
1035   if (maj_stat != GSS_S_COMPLETE) {
1036     display_gssapi_status("Failuring acquiring GSSAPI credentials",
1037                           maj_stat, min_stat);
1038     gss_cred = GSS_C_NO_CREDENTIAL; /* should not be needed */
1039     return 0;
1040   }
1041
1042   return 1;     /* Success */
1043 }
1044
1045 char * get_gss_our_name()
1046 {
1047   OM_uint32 maj_stat;
1048   OM_uint32 min_stat;
1049   gss_name_t pname = GSS_C_NO_NAME;
1050   gss_buffer_desc tmpname;
1051   gss_buffer_t tmpnamed = &tmpname;
1052   char *retname;
1053
1054   debug("calling gss_inquire_cred");
1055   maj_stat = gss_inquire_cred(&min_stat,
1056                               gss_cred,
1057                               &pname,
1058                               NULL,
1059                               NULL,
1060                               NULL);
1061   if (maj_stat != GSS_S_COMPLETE) {
1062     return NULL;
1063   }
1064
1065   maj_stat = gss_export_name(&min_stat,
1066                              pname,
1067                              tmpnamed);
1068   if (maj_stat != GSS_S_COMPLETE) {
1069     return NULL;
1070   }
1071   debug("gss_export_name finsished");
1072   retname = (char *)malloc(tmpname.length + 1);
1073   if (!retname) {
1074     return NULL;
1075   }
1076   memcpy(retname, tmpname.value, tmpname.length);
1077   retname[tmpname.length] = '\0';
1078
1079   gss_release_name(&min_stat, &pname);
1080   gss_release_buffer(&min_stat, tmpnamed);
1081
1082   return retname;
1083 }
1084 #endif /* GSI */
1085
1086 int try_gssapi_authentication(char *host, Options *options)
1087 {
1088   char *service_name = NULL;
1089   gss_buffer_desc name_tok;
1090   gss_buffer_desc send_tok;
1091   gss_buffer_desc recv_tok;
1092   gss_buffer_desc *token_ptr;
1093   gss_name_t target_name = NULL;
1094   gss_ctx_id_t gss_context;
1095   gss_OID_desc mech_oid;
1096   gss_OID name_type;
1097   gss_OID_set my_mechs;
1098   int my_mech_num;
1099   OM_uint32 maj_stat;
1100   OM_uint32 min_stat;
1101   int ret_stat = 0;                             /* 1 == success */
1102   OM_uint32 req_flags = 0;
1103   OM_uint32 ret_flags;
1104   int type;
1105   char *gssapi_auth_type = NULL;
1106   struct hostent *hostinfo;
1107   int len;
1108
1109
1110   /*
1111    * host is not guarenteed to be a FQDN, so we need to make sure it is.
1112    */
1113   hostinfo = gethostbyname(host);
1114
1115   if ((hostinfo == NULL) || (hostinfo->h_name == NULL)) {
1116       debug("GSSAPI authentication: Unable to get FQDN for \"%s\"", host);
1117       goto cleanup;
1118   }
1119
1120   /*
1121    * Default flags
1122    */
1123   req_flags |= GSS_C_REPLAY_FLAG;
1124
1125   /* Do mutual authentication */
1126   req_flags |= GSS_C_MUTUAL_FLAG;
1127
1128 #ifdef GSSAPI_KRB5
1129
1130   gssapi_auth_type = "GSSAPI/Kerberos 5";
1131
1132 #endif /* GSSAPI_KRB5 */
1133
1134 #ifdef GSI
1135
1136   gssapi_auth_type = "GSSAPI/GLOBUS";
1137
1138 #endif /* GSI */
1139
1140   if (gssapi_auth_type == NULL) {
1141       debug("No GSSAPI type defined during compile");
1142       goto cleanup;
1143   }
1144
1145   debug("Attempting %s authentication", gssapi_auth_type);
1146
1147   service_name = (char *) malloc(strlen(GSSAPI_SERVICE_NAME) +
1148                                  strlen(hostinfo->h_name) +
1149                                  2 /* 1 for '@', 1 for NUL */);
1150
1151   if (service_name == NULL) {
1152     debug("malloc() failed");
1153     goto cleanup;
1154   }
1155
1156
1157   sprintf(service_name, "%s@%s", GSSAPI_SERVICE_NAME, hostinfo->h_name);
1158
1159   name_type = GSS_C_NT_HOSTBASED_SERVICE;
1160
1161   debug("Service name is %s", service_name);
1162
1163   /* Forward credentials? */
1164
1165 #ifdef GSSAPI_KRB5
1166   if (options->kerberos_tgt_passing) {
1167       debug("Forwarding Kerberos credentials");
1168       req_flags |= GSS_C_DELEG_FLAG;
1169   }
1170 #endif /* GSSAPI_KRB5 */
1171
1172 #ifdef GSI
1173   if(options->forward_gssapi_globus_proxy) {
1174     debug("Forwarding X509 proxy certificate");
1175     req_flags |= GSS_C_DELEG_FLAG;
1176   }
1177 #ifdef GSS_C_GLOBUS_LIMITED_DELEG_PROXY_FLAG
1178   /* Forward limited credentials, overrides forward_gssapi_globus_proxy */
1179   if(options->forward_gssapi_globus_limited_proxy) {
1180     debug("Forwarding limited X509 proxy certificate");
1181     req_flags |= (GSS_C_DELEG_FLAG | GSS_C_GLOBUS_LIMITED_DELEG_PROXY_FLAG);
1182   }
1183 #endif /* GSS_C_GLOBUS_LIMITED_DELEG_PROXY_FLAG */
1184
1185 #endif /* GSI */
1186
1187   debug("req_flags = %lu", req_flags);
1188
1189   name_tok.value = service_name;
1190   name_tok.length = strlen(service_name) + 1;
1191   maj_stat = gss_import_name(&min_stat, &name_tok,
1192                              name_type, &target_name);
1193
1194   free(service_name);
1195   service_name = NULL;
1196
1197   if (maj_stat != GSS_S_COMPLETE) {
1198     display_gssapi_status("importing service name", maj_stat, min_stat);
1199     goto cleanup;
1200   }
1201
1202   maj_stat = gss_indicate_mechs(&min_stat, &my_mechs);
1203
1204   if (maj_stat != GSS_S_COMPLETE) {
1205     display_gssapi_status("indicating mechs", maj_stat, min_stat);
1206     goto cleanup;
1207   }
1208
1209   /*
1210    * Send over a packet to the daemon, letting it know we're doing
1211    * GSSAPI and our mech_oid(s).
1212    */
1213   debug("Sending mech oid to server");
1214   packet_start(SSH_CMSG_AUTH_GSSAPI);
1215   packet_put_int(my_mechs->count); /* Number of mechs we're sending */
1216   for (my_mech_num = 0; my_mech_num < my_mechs->count; my_mech_num++)
1217       packet_put_string(my_mechs->elements[my_mech_num].elements,
1218                         my_mechs->elements[my_mech_num].length);
1219   packet_send();
1220   packet_write_wait();
1221
1222   /*
1223    * Get reply from the daemon to see if our mech was acceptable
1224    */
1225   type = packet_read(&len);
1226
1227   switch (type) {
1228   case SSH_SMSG_AUTH_GSSAPI_RESPONSE:
1229       debug("Server accepted mechanism");
1230       /* Successful negotiation */
1231       break;
1232
1233   case SSH_MSG_AUTH_GSSAPI_ABORT:
1234       debug("Unable to negotiate GSSAPI mechanism type with server");
1235       packet_get_all();
1236       goto cleanup;
1237
1238   default:
1239       packet_disconnect("Protocol error during GSSAPI authentication:"
1240                         " packet type %d received",
1241                         type);
1242       /* Does not return */
1243   }
1244
1245   /* Read the mechanism the server returned */
1246   mech_oid.elements = packet_get_string((unsigned int *) &(mech_oid.length));
1247   packet_get_all();
1248
1249   /*
1250    * Perform the context-establishement loop.
1251    *
1252    * On each pass through the loop, token_ptr points to the token
1253    * to send to the server (or GSS_C_NO_BUFFER on the first pass).
1254    * Every generated token is stored in send_tok which is then
1255    * transmitted to the server; every received token is stored in
1256    * recv_tok, which token_ptr is then set to, to be processed by
1257    * the next call to gss_init_sec_context.
1258    *
1259    * GSS-API guarantees that send_tok's length will be non-zero
1260    * if and only if the server is expecting another token from us,
1261    * and that gss_init_sec_context returns GSS_S_CONTINUE_NEEDED if
1262    * and only if the server has another token to send us.
1263    */
1264
1265   token_ptr = GSS_C_NO_BUFFER;
1266   gss_context = GSS_C_NO_CONTEXT;
1267
1268   do {
1269     maj_stat =
1270       gss_init_sec_context(&min_stat,
1271                            gss_cred,
1272                            &gss_context,
1273                            target_name,
1274                            &mech_oid,
1275                            req_flags,
1276                            0,
1277                            NULL,        /* no channel bindings */
1278                            token_ptr,
1279                            NULL,        /* ignore mech type */
1280                            &send_tok,
1281                            &ret_flags,
1282                            NULL);       /* ignore time_rec */
1283
1284     if (token_ptr != GSS_C_NO_BUFFER)
1285       (void) gss_release_buffer(&min_stat, &recv_tok);
1286
1287     if (maj_stat != GSS_S_COMPLETE && maj_stat != GSS_S_CONTINUE_NEEDED) {
1288       display_gssapi_status("initializing context", maj_stat, min_stat);
1289
1290       /* Send an abort message */
1291       packet_start(SSH_MSG_AUTH_GSSAPI_ABORT);
1292       packet_send();
1293       packet_write_wait();
1294
1295       goto cleanup;
1296     }
1297
1298     if (send_tok.length != 0) {
1299       debug("Sending authenticaton token...");
1300       packet_start(SSH_MSG_AUTH_GSSAPI_TOKEN);
1301       packet_put_string((char *) send_tok.value, send_tok.length);
1302       packet_send();
1303       packet_write_wait();
1304
1305       (void) gss_release_buffer(&min_stat, &send_tok);
1306     }
1307
1308     if (maj_stat == GSS_S_CONTINUE_NEEDED) {
1309
1310       debug("Continue needed. Reading response...");
1311
1312       type = packet_read(&len);
1313
1314       switch(type) {
1315
1316       case SSH_MSG_AUTH_GSSAPI_TOKEN:
1317         /* This is what we expected */
1318         break;
1319
1320       case SSH_MSG_AUTH_GSSAPI_ABORT:
1321         debug("Server aborted GSSAPI authentication.");
1322         packet_get_all();
1323         goto cleanup;
1324
1325       default:
1326         packet_disconnect("Protocol error during GSSAPI authentication:"
1327                           " packet type %d received",
1328                           type);
1329         /* Does not return */
1330       }
1331
1332       recv_tok.value = packet_get_string((unsigned int *) &recv_tok.length);
1333       packet_get_all();
1334       token_ptr = &recv_tok;
1335     }
1336   } while (maj_stat == GSS_S_CONTINUE_NEEDED);
1337
1338   /* Success */
1339   ret_stat = 1;
1340
1341   debug("%s authentication successful", gssapi_auth_type);
1342
1343   /*
1344    * Read hash of host and server keys and make sure it
1345    * matches what we got earlier.
1346    */
1347   debug("Reading hash of server and host keys...");
1348   type = packet_read(&len);
1349
1350   if (type == SSH_MSG_AUTH_GSSAPI_ABORT) {
1351     debug("Server aborted GSSAPI authentication.");
1352     packet_get_all();
1353     ret_stat = 0;
1354     goto cleanup;
1355
1356   } else if (type == SSH_SMSG_AUTH_GSSAPI_HASH) {
1357     gss_buffer_desc wrapped_buf;
1358     gss_buffer_desc unwrapped_buf;
1359     int conf_state;
1360     gss_qop_t qop_state;
1361
1362
1363     wrapped_buf.value = packet_get_string(&(wrapped_buf.length));
1364     packet_get_all();
1365
1366     maj_stat = gss_unwrap(&min_stat,
1367                           gss_context,
1368                           &wrapped_buf,
1369                           &unwrapped_buf,
1370                           &conf_state,
1371                           &qop_state);
1372
1373     if (maj_stat != GSS_S_COMPLETE) {
1374       display_gssapi_status("unwraping SSHD key hash",
1375                             maj_stat, min_stat);
1376       packet_disconnect("Verification of SSHD keys through GSSAPI-secured channel failed: "
1377                         "Unwrapping of hash failed.");
1378     }
1379
1380     if (unwrapped_buf.length != sizeof(ssh_key_digest)) {
1381       packet_disconnect("Verification of SSHD keys through GSSAPI-secured channel failed: "
1382                         "Size of key hashes do not match (%d != %d)!",
1383                         unwrapped_buf.length, sizeof(ssh_key_digest));
1384     }
1385
1386     if (memcmp(ssh_key_digest, unwrapped_buf.value, sizeof(ssh_key_digest)) != 0) {
1387       packet_disconnect("Verification of SSHD keys through GSSAPI-secured channel failed: "
1388                         "Hashes don't match!");
1389     }
1390
1391     debug("Verified SSHD keys through GSSAPI-secured channel.");
1392
1393     gss_release_buffer(&min_stat, &unwrapped_buf);
1394
1395   } else {
1396       packet_disconnect("Protocol error during GSSAPI authentication:"
1397                         "packet type %d received", type);
1398       /* Does not return */
1399   }
1400
1401
1402  cleanup:
1403   if (target_name != NULL)
1404       (void) gss_release_name(&min_stat, &target_name);
1405
1406   return ret_stat;
1407 }
1408
1409 #endif /* GSSAPI */
1410
1411 /*end of modification*/
1412
1413 /*
1414  * SSH1 key exchange
1415  */
1416 void
1417 ssh_kex(char *host, struct sockaddr *hostaddr)
1418 {
1419         int i;
1420         BIGNUM *key;
1421         RSA *host_key;
1422         RSA *public_key;
1423         Key k;
1424         int bits, rbits;
1425         int ssh_cipher_default = SSH_CIPHER_3DES;
1426         u_char session_key[SSH_SESSION_KEY_LENGTH];
1427         u_char cookie[8];
1428         u_int supported_ciphers;
1429         u_int server_flags, client_flags;
1430         int payload_len, clen, sum_len = 0;
1431         u_int32_t rand = 0;
1432
1433         debug("Waiting for server public key.");
1434
1435         /* Wait for a public key packet from the server. */
1436         packet_read_expect(&payload_len, SSH_SMSG_PUBLIC_KEY);
1437
1438         /* Get cookie from the packet. */
1439         for (i = 0; i < 8; i++)
1440                 cookie[i] = packet_get_char();
1441
1442         /* Get the public key. */
1443         public_key = RSA_new();
1444         bits = packet_get_int();/* bits */
1445         public_key->e = BN_new();
1446         packet_get_bignum(public_key->e, &clen);
1447         sum_len += clen;
1448         public_key->n = BN_new();
1449         packet_get_bignum(public_key->n, &clen);
1450         sum_len += clen;
1451
1452         rbits = BN_num_bits(public_key->n);
1453         if (bits != rbits) {
1454                 log("Warning: Server lies about size of server public key: "
1455                     "actual size is %d bits vs. announced %d.", rbits, bits);
1456                 log("Warning: This may be due to an old implementation of ssh.");
1457         }
1458         /* Get the host key. */
1459         host_key = RSA_new();
1460         bits = packet_get_int();/* bits */
1461         host_key->e = BN_new();
1462         packet_get_bignum(host_key->e, &clen);
1463         sum_len += clen;
1464         host_key->n = BN_new();
1465         packet_get_bignum(host_key->n, &clen);
1466         sum_len += clen;
1467
1468         rbits = BN_num_bits(host_key->n);
1469         if (bits != rbits) {
1470                 log("Warning: Server lies about size of server host key: "
1471                     "actual size is %d bits vs. announced %d.", rbits, bits);
1472                 log("Warning: This may be due to an old implementation of ssh.");
1473         }
1474
1475 /*modified by binhe*/
1476 #ifdef GSSAPI
1477   {
1478     MD5_CTX md5context;
1479     Buffer buf;
1480     unsigned char *data;
1481     unsigned int data_len;
1482
1483     /*
1484      * Hash the server and host keys. Later we will check them against
1485      * a hash sent over a secure channel to make sure they are legit.
1486      */
1487     debug("Calculating MD5 hash of server and host keys...");
1488
1489     /* Write all the keys to a temporary buffer */
1490     buffer_init(&buf);
1491
1492     /* Server key */
1493     buffer_put_bignum(&buf, public_key->e);
1494     buffer_put_bignum(&buf, public_key->n);
1495
1496     /* Host key */
1497     buffer_put_bignum(&buf, host_key->e);
1498     buffer_put_bignum(&buf, host_key->n);
1499
1500     /* Get the resulting data */
1501     data = (unsigned char *) buffer_ptr(&buf);
1502     data_len = buffer_len(&buf);
1503
1504     /* And hash it */
1505     MD5_Init(&md5context);
1506     MD5_Update(&md5context, data, data_len);
1507     MD5_Final(ssh_key_digest, &md5context);
1508
1509     /* Clean up */
1510     buffer_clear(&buf);
1511     buffer_free(&buf);
1512   }
1513 #endif /* GSSAPI */
1514 /*end of modification*/
1515
1516         /* Get protocol flags. */
1517         server_flags = packet_get_int();
1518         packet_set_protocol_flags(server_flags);
1519
1520         supported_ciphers = packet_get_int();
1521         supported_authentications = packet_get_int();
1522
1523         debug("Received server public key (%d bits) and host key (%d bits).",
1524               BN_num_bits(public_key->n), BN_num_bits(host_key->n));
1525
1526         packet_integrity_check(payload_len,
1527                                8 + 4 + sum_len + 0 + 4 + 0 + 0 + 4 + 4 + 4,
1528                                SSH_SMSG_PUBLIC_KEY);
1529         k.type = KEY_RSA1;
1530         k.rsa = host_key;
1531         if (verify_host_key(host, hostaddr, &k) == -1)
1532                 fatal("Host key verification failed.");
1533
1534         client_flags = SSH_PROTOFLAG_SCREEN_NUMBER | SSH_PROTOFLAG_HOST_IN_FWD_OPEN;
1535
1536         compute_session_id(session_id, cookie, host_key->n, public_key->n);
1537
1538         /* Generate a session key. */
1539         arc4random_stir();
1540
1541         /*
1542          * Generate an encryption key for the session.   The key is a 256 bit
1543          * random number, interpreted as a 32-byte key, with the least
1544          * significant 8 bits being the first byte of the key.
1545          */
1546         for (i = 0; i < 32; i++) {
1547                 if (i % 4 == 0)
1548                         rand = arc4random();
1549                 session_key[i] = rand & 0xff;
1550                 rand >>= 8;
1551         }
1552
1553         /*
1554          * According to the protocol spec, the first byte of the session key
1555          * is the highest byte of the integer.  The session key is xored with
1556          * the first 16 bytes of the session id.
1557          */
1558         key = BN_new();
1559         BN_set_word(key, 0);
1560         for (i = 0; i < SSH_SESSION_KEY_LENGTH; i++) {
1561                 BN_lshift(key, key, 8);
1562                 if (i < 16)
1563                         BN_add_word(key, session_key[i] ^ session_id[i]);
1564                 else
1565                         BN_add_word(key, session_key[i]);
1566         }
1567
1568         /*
1569          * Encrypt the integer using the public key and host key of the
1570          * server (key with smaller modulus first).
1571          */
1572         if (BN_cmp(public_key->n, host_key->n) < 0) {
1573                 /* Public key has smaller modulus. */
1574                 if (BN_num_bits(host_key->n) <
1575                     BN_num_bits(public_key->n) + SSH_KEY_BITS_RESERVED) {
1576                         fatal("respond_to_rsa_challenge: host_key %d < public_key %d + "
1577                               "SSH_KEY_BITS_RESERVED %d",
1578                               BN_num_bits(host_key->n),
1579                               BN_num_bits(public_key->n),
1580                               SSH_KEY_BITS_RESERVED);
1581                 }
1582                 rsa_public_encrypt(key, key, public_key);
1583                 rsa_public_encrypt(key, key, host_key);
1584         } else {
1585                 /* Host key has smaller modulus (or they are equal). */
1586                 if (BN_num_bits(public_key->n) <
1587                     BN_num_bits(host_key->n) + SSH_KEY_BITS_RESERVED) {
1588                         fatal("respond_to_rsa_challenge: public_key %d < host_key %d + "
1589                               "SSH_KEY_BITS_RESERVED %d",
1590                               BN_num_bits(public_key->n),
1591                               BN_num_bits(host_key->n),
1592                               SSH_KEY_BITS_RESERVED);
1593                 }
1594                 rsa_public_encrypt(key, key, host_key);
1595                 rsa_public_encrypt(key, key, public_key);
1596         }
1597
1598         /* Destroy the public keys since we no longer need them. */
1599         RSA_free(public_key);
1600         RSA_free(host_key);
1601
1602         if (options.cipher == SSH_CIPHER_NOT_SET) {
1603                 if (cipher_mask_ssh1(1) & supported_ciphers & (1 << ssh_cipher_default))
1604                         options.cipher = ssh_cipher_default;
1605         } else if (options.cipher == SSH_CIPHER_ILLEGAL ||
1606             !(cipher_mask_ssh1(1) & (1 << options.cipher))) {
1607                 log("No valid SSH1 cipher, using %.100s instead.",
1608                     cipher_name(ssh_cipher_default));
1609                 options.cipher = ssh_cipher_default;
1610         }
1611         /* Check that the selected cipher is supported. */
1612         if (!(supported_ciphers & (1 << options.cipher)))
1613                 fatal("Selected cipher type %.100s not supported by server.",
1614                       cipher_name(options.cipher));
1615
1616         debug("Encryption type: %.100s", cipher_name(options.cipher));
1617
1618         /* Send the encrypted session key to the server. */
1619         packet_start(SSH_CMSG_SESSION_KEY);
1620         packet_put_char(options.cipher);
1621
1622         /* Send the cookie back to the server. */
1623         for (i = 0; i < 8; i++)
1624                 packet_put_char(cookie[i]);
1625
1626         /* Send and destroy the encrypted encryption key integer. */
1627         packet_put_bignum(key);
1628         BN_clear_free(key);
1629
1630         /* Send protocol flags. */
1631         packet_put_int(client_flags);
1632
1633         /* Send the packet now. */
1634         packet_send();
1635         packet_write_wait();
1636
1637         debug("Sent encrypted session key.");
1638
1639         /* Set the encryption key. */
1640         packet_set_encryption_key(session_key, SSH_SESSION_KEY_LENGTH, options.cipher);
1641
1642         /* We will no longer need the session key here.  Destroy any extra copies. */
1643         memset(session_key, 0, sizeof(session_key));
1644
1645         /*
1646          * Expect a success message from the server.  Note that this message
1647          * will be received in encrypted form.
1648          */
1649         packet_read_expect(&payload_len, SSH_SMSG_SUCCESS);
1650
1651         debug("Received encrypted confirmation.");
1652 }
1653
1654 /*
1655  * Authenticate user
1656  */
1657 void
1658 ssh_userauth1(const char *local_user, const char *server_user, char *host,
1659     Key **keys, int nkeys)
1660 {
1661 /*modified by binhe*/
1662 #ifdef GSSAPI
1663 #ifdef GSI
1664         const char *save_server_user = NULL;
1665 #endif /* GSI */
1666 #endif /* GSSAPI */
1667 /*end of modification*/
1668
1669 #ifdef KRB5
1670         krb5_context context = NULL;
1671         krb5_auth_context auth_context = NULL;
1672 #endif
1673         int i, type;
1674         int payload_len;
1675         
1676         if (supported_authentications == 0)
1677                 fatal("ssh_userauth1: server supports no auth methods");
1678
1679 /*modified by binhe*/
1680 #ifdef GSSAPI
1681 #ifdef GSI
1682   /* if no user given, tack on the subject name after the server_user.
1683    * This will allow us to run gridmap early to get real user
1684    * This name will start with /C=
1685    */
1686   if ((supported_authentications & (1 << SSH_AUTH_GSSAPI)) &&
1687       options.gss_authentication) {
1688     if (get_gssapi_cred()) {
1689       char * retname;
1690       char * newname;
1691
1692
1693       save_server_user = server_user;
1694
1695       retname = get_gss_our_name();
1696
1697       if (retname) {
1698         debug("passing gssapi name '%s'", retname);
1699         if (server_user) {
1700           newname = (char *) malloc(strlen(retname) + strlen(server_user) + 4);
1701           if (newname) {
1702             strcpy(newname, server_user);
1703             if(options.user == NULL)
1704               {
1705                 strcat(newname,":i:");
1706               }
1707             else
1708               {
1709                 strcat(newname,":x:");
1710               }
1711             strcat(newname, retname);
1712             server_user = newname;
1713             free(retname);
1714           }
1715         }
1716       }
1717     } else {
1718       /*
1719        * If we couldn't successfully get our GSSAPI credentials then
1720        * turn off gssapi authentication
1721        */
1722       options.gss_authentication = 0;
1723     }
1724     debug("server_user %s", server_user);
1725   }
1726 #endif /* GSI */
1727 #endif /* GSSAPI */
1728 /*end of modification*/
1729
1730         /* Send the name of the user to log in as on the server. */
1731         packet_start(SSH_CMSG_USER);
1732         packet_put_cstring(server_user);
1733         packet_send();
1734         packet_write_wait();
1735
1736 /*modified by binhe*/
1737 #if defined(GSI)
1738   if(save_server_user)
1739     {
1740       server_user = save_server_user;
1741     }
1742 #endif
1743 /*end of modification*/
1744         /*
1745          * The server should respond with success if no authentication is
1746          * needed (the user has no password).  Otherwise the server responds
1747          * with failure.
1748          */
1749         type = packet_read(&payload_len);
1750
1751         /* check whether the connection was accepted without authentication. */
1752         if (type == SSH_SMSG_SUCCESS)
1753                 goto success;
1754         if (type != SSH_SMSG_FAILURE)
1755                 packet_disconnect("Protocol error: got %d in response to SSH_CMSG_USER", type);
1756
1757 /*modified by binhe*/
1758 #ifdef GSSAPI
1759   /* Try GSSAPI authentication */
1760   if ((supported_authentications & (1 << SSH_AUTH_GSSAPI)) &&
1761       options.gss_authentication)
1762     {
1763       debug("Trying GSSAPI authentication (%s)...", gssapi_patch_version);
1764       try_gssapi_authentication(host, &options);
1765
1766       /*
1767        * XXX Hmmm. Kerberos authentication only reads a packet if it thinks
1768        * the authentication went OK, but the server seems to always send
1769        * a packet back. So I'm not sure if I'm missing something or
1770        * the Kerberos code is broken. - vwelch 1/27/99
1771        */
1772
1773       type = packet_read(&payload_len);
1774       if (type == SSH_SMSG_SUCCESS)
1775         return; /* Successful connection. */
1776       if (type != SSH_SMSG_FAILURE)
1777         packet_disconnect("Protocol error: got %d in response to Kerberos auth", type);
1778
1779       debug("GSSAPI authentication failed");
1780     }
1781 #endif /* GSSAPI */
1782 /*end of modification*/
1783         
1784 #ifdef KRB5
1785         if ((supported_authentications & (1 << SSH_AUTH_KERBEROS)) &&
1786             options.kerberos_authentication) {
1787                 debug("Trying Kerberos v5 authentication.");
1788                 
1789                 if (try_krb5_authentication(&context, &auth_context)) {
1790                         type = packet_read(&payload_len);
1791                         if (type == SSH_SMSG_SUCCESS)
1792                                 goto success;
1793                         if (type != SSH_SMSG_FAILURE)
1794                                 packet_disconnect("Protocol error: got %d in response to Kerberos v5 auth", type);
1795                 }
1796         }
1797 #endif /* KRB5 */
1798         
1799 #ifdef KRB4
1800         if ((supported_authentications & (1 << SSH_AUTH_KERBEROS)) &&
1801             options.kerberos_authentication) {
1802                 debug("Trying Kerberos v4 authentication.");
1803                 
1804                 if (try_krb4_authentication()) {
1805                         type = packet_read(&payload_len);
1806                         if (type == SSH_SMSG_SUCCESS)
1807                                 goto success;
1808                         if (type != SSH_SMSG_FAILURE)
1809                                 packet_disconnect("Protocol error: got %d in response to Kerberos v4 auth", type);
1810                 }
1811         }
1812 #endif /* KRB4 */
1813         
1814         /*
1815          * Use rhosts authentication if running in privileged socket and we
1816          * do not wish to remain anonymous.
1817          */
1818         if ((supported_authentications & (1 << SSH_AUTH_RHOSTS)) &&
1819             options.rhosts_authentication) {
1820                 debug("Trying rhosts authentication.");
1821                 packet_start(SSH_CMSG_AUTH_RHOSTS);
1822                 packet_put_cstring(local_user);
1823                 packet_send();
1824                 packet_write_wait();
1825
1826                 /* The server should respond with success or failure. */
1827                 type = packet_read(&payload_len);
1828                 if (type == SSH_SMSG_SUCCESS)
1829                         goto success;
1830                 if (type != SSH_SMSG_FAILURE)
1831                         packet_disconnect("Protocol error: got %d in response to rhosts auth",
1832                                           type);
1833         }
1834         /*
1835          * Try .rhosts or /etc/hosts.equiv authentication with RSA host
1836          * authentication.
1837          */
1838         if ((supported_authentications & (1 << SSH_AUTH_RHOSTS_RSA)) &&
1839             options.rhosts_rsa_authentication) {
1840                 for (i = 0; i < nkeys; i++) {
1841                         if (keys[i] != NULL && keys[i]->type == KEY_RSA1 &&
1842                             try_rhosts_rsa_authentication(local_user, keys[i]))
1843                                 goto success;
1844                 }
1845         }
1846         /* Try RSA authentication if the server supports it. */
1847         if ((supported_authentications & (1 << SSH_AUTH_RSA)) &&
1848             options.rsa_authentication) {
1849                 /*
1850                  * Try RSA authentication using the authentication agent. The
1851                  * agent is tried first because no passphrase is needed for
1852                  * it, whereas identity files may require passphrases.
1853                  */
1854                 if (try_agent_authentication())
1855                         goto success;
1856
1857                 /* Try RSA authentication for each identity. */
1858                 for (i = 0; i < options.num_identity_files; i++)
1859                         if (options.identity_keys[i] != NULL &&
1860                             options.identity_keys[i]->type == KEY_RSA1 &&
1861                             try_rsa_authentication(i))
1862                                 goto success;
1863         }
1864         /* Try challenge response authentication if the server supports it. */
1865         if ((supported_authentications & (1 << SSH_AUTH_TIS)) &&
1866             options.challenge_response_authentication && !options.batch_mode) {
1867                 if (try_challenge_response_authentication())
1868                         goto success;
1869         }
1870         /* Try password authentication if the server supports it. */
1871         if ((supported_authentications & (1 << SSH_AUTH_PASSWORD)) &&
1872             options.password_authentication && !options.batch_mode) {
1873                 char prompt[80];
1874
1875                 snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password: ",
1876                     server_user, host);
1877                 if (try_password_authentication(prompt))
1878                         goto success;
1879         }
1880         /* All authentication methods have failed.  Exit with an error message. */
1881         fatal("Permission denied.");
1882         /* NOTREACHED */
1883
1884  success:
1885 #ifdef KRB5
1886         /* Try Kerberos v5 TGT passing. */
1887         if ((supported_authentications & (1 << SSH_PASS_KERBEROS_TGT)) &&
1888             options.kerberos_tgt_passing && context && auth_context) {
1889                 if (options.cipher == SSH_CIPHER_NONE)
1890                         log("WARNING: Encryption is disabled! Ticket will be transmitted in the clear!");
1891                 send_krb5_tgt(context, auth_context);
1892         }
1893         if (auth_context)
1894                 krb5_auth_con_free(context, auth_context);
1895         if (context)
1896                 krb5_free_context(context);
1897 #endif
1898         
1899 #ifdef AFS
1900         /* Try Kerberos v4 TGT passing if the server supports it. */
1901         if ((supported_authentications & (1 << SSH_PASS_KERBEROS_TGT)) &&
1902             options.kerberos_tgt_passing) {
1903                 if (options.cipher == SSH_CIPHER_NONE)
1904                         log("WARNING: Encryption is disabled! Ticket will be transmitted in the clear!");
1905                 send_krb4_tgt();
1906         }
1907         /* Try AFS token passing if the server supports it. */
1908         if ((supported_authentications & (1 << SSH_PASS_AFS_TOKEN)) &&
1909             options.afs_token_passing && k_hasafs()) {
1910                 if (options.cipher == SSH_CIPHER_NONE)
1911                         log("WARNING: Encryption is disabled! Token will be transmitted in the clear!");
1912                 send_afs_tokens();
1913         }
1914 #endif /* AFS */
1915
1916         return; /* need statement after label */
1917 }
This page took 0.196839 seconds and 5 git commands to generate.