source: trunk/third/openssh/sshconnect1.c @ 19235

Revision 19235, 38.4 KB checked in by zacheiss, 22 years ago (diff)
Backwards compatability with ssh.com sshds which expect you to forward credentials before you authenticate.
Line 
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"
16RCSID("$OpenBSD: sshconnect1.c,v 1.52 2002/08/08 13:50:23 aaron Exp $");
17
18#include <openssl/bn.h>
19#include <openssl/md5.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#include "compat.h"
54
55/* Session id for the current session. */
56u_char session_id[16];
57u_int supported_authentications = 0;
58
59extern Options options;
60extern char *__progname;
61
62/*
63 * Checks if the user has an authentication agent, and if so, tries to
64 * authenticate using the agent.
65 */
66static int
67try_agent_authentication(void)
68{
69        int type;
70        char *comment;
71        AuthenticationConnection *auth;
72        u_char response[16];
73        u_int i;
74        Key *key;
75        BIGNUM *challenge;
76
77        /* Get connection to the agent. */
78        auth = ssh_get_authentication_connection();
79        if (!auth)
80                return 0;
81
82        if ((challenge = BN_new()) == NULL)
83                fatal("try_agent_authentication: BN_new failed");
84        /* Loop through identities served by the agent. */
85        for (key = ssh_get_first_identity(auth, &comment, 1);
86            key != NULL;
87            key = ssh_get_next_identity(auth, &comment, 1)) {
88
89                /* Try this identity. */
90                debug("Trying RSA authentication via agent with '%.100s'", comment);
91                xfree(comment);
92
93                /* Tell the server that we are willing to authenticate using this key. */
94                packet_start(SSH_CMSG_AUTH_RSA);
95                packet_put_bignum(key->rsa->n);
96                packet_send();
97                packet_write_wait();
98
99                /* Wait for server's response. */
100                type = packet_read();
101
102                /* The server sends failure if it doesn\'t like our key or
103                   does not support RSA authentication. */
104                if (type == SSH_SMSG_FAILURE) {
105                        debug("Server refused our key.");
106                        key_free(key);
107                        continue;
108                }
109                /* Otherwise it should have sent a challenge. */
110                if (type != SSH_SMSG_AUTH_RSA_CHALLENGE)
111                        packet_disconnect("Protocol error during RSA authentication: %d",
112                                          type);
113
114                packet_get_bignum(challenge);
115                packet_check_eom();
116
117                debug("Received RSA challenge from server.");
118
119                /* Ask the agent to decrypt the challenge. */
120                if (!ssh_decrypt_challenge(auth, key, challenge, session_id, 1, response)) {
121                        /*
122                         * The agent failed to authenticate this identifier
123                         * although it advertised it supports this.  Just
124                         * return a wrong value.
125                         */
126                        log("Authentication agent failed to decrypt challenge.");
127                        memset(response, 0, sizeof(response));
128                }
129                key_free(key);
130                debug("Sending response to RSA challenge.");
131
132                /* Send the decrypted challenge back to the server. */
133                packet_start(SSH_CMSG_AUTH_RSA_RESPONSE);
134                for (i = 0; i < 16; i++)
135                        packet_put_char(response[i]);
136                packet_send();
137                packet_write_wait();
138
139                /* Wait for response from the server. */
140                type = packet_read();
141
142                /* The server returns success if it accepted the authentication. */
143                if (type == SSH_SMSG_SUCCESS) {
144                        ssh_close_authentication_connection(auth);
145                        BN_clear_free(challenge);
146                        debug("RSA authentication accepted by server.");
147                        return 1;
148                }
149                /* Otherwise it should return failure. */
150                if (type != SSH_SMSG_FAILURE)
151                        packet_disconnect("Protocol error waiting RSA auth response: %d",
152                                          type);
153        }
154        ssh_close_authentication_connection(auth);
155        BN_clear_free(challenge);
156        debug("RSA authentication using agent refused.");
157        return 0;
158}
159
160/*
161 * Computes the proper response to a RSA challenge, and sends the response to
162 * the server.
163 */
164static void
165respond_to_rsa_challenge(BIGNUM * challenge, RSA * prv)
166{
167        u_char buf[32], response[16];
168        MD5_CTX md;
169        int i, len;
170
171        /* Decrypt the challenge using the private key. */
172        /* XXX think about Bleichenbacher, too */
173        if (rsa_private_decrypt(challenge, challenge, prv) <= 0)
174                packet_disconnect(
175                    "respond_to_rsa_challenge: rsa_private_decrypt failed");
176
177        /* Compute the response. */
178        /* The response is MD5 of decrypted challenge plus session id. */
179        len = BN_num_bytes(challenge);
180        if (len <= 0 || len > sizeof(buf))
181                packet_disconnect(
182                    "respond_to_rsa_challenge: bad challenge length %d", len);
183
184        memset(buf, 0, sizeof(buf));
185        BN_bn2bin(challenge, buf + sizeof(buf) - len);
186        MD5_Init(&md);
187        MD5_Update(&md, buf, 32);
188        MD5_Update(&md, session_id, 16);
189        MD5_Final(response, &md);
190
191        debug("Sending response to host key RSA challenge.");
192
193        /* Send the response back to the server. */
194        packet_start(SSH_CMSG_AUTH_RSA_RESPONSE);
195        for (i = 0; i < 16; i++)
196                packet_put_char(response[i]);
197        packet_send();
198        packet_write_wait();
199
200        memset(buf, 0, sizeof(buf));
201        memset(response, 0, sizeof(response));
202        memset(&md, 0, sizeof(md));
203}
204
205/*
206 * Checks if the user has authentication file, and if so, tries to authenticate
207 * the user using it.
208 */
209static int
210try_rsa_authentication(int idx)
211{
212        BIGNUM *challenge;
213        Key *public, *private;
214        char buf[300], *passphrase, *comment, *authfile;
215        int i, type, quit;
216
217        public = options.identity_keys[idx];
218        authfile = options.identity_files[idx];
219        comment = xstrdup(authfile);
220
221        debug("Trying RSA authentication with key '%.100s'", comment);
222
223        /* Tell the server that we are willing to authenticate using this key. */
224        packet_start(SSH_CMSG_AUTH_RSA);
225        packet_put_bignum(public->rsa->n);
226        packet_send();
227        packet_write_wait();
228
229        /* Wait for server's response. */
230        type = packet_read();
231
232        /*
233         * The server responds with failure if it doesn\'t like our key or
234         * doesn\'t support RSA authentication.
235         */
236        if (type == SSH_SMSG_FAILURE) {
237                debug("Server refused our key.");
238                xfree(comment);
239                return 0;
240        }
241        /* Otherwise, the server should respond with a challenge. */
242        if (type != SSH_SMSG_AUTH_RSA_CHALLENGE)
243                packet_disconnect("Protocol error during RSA authentication: %d", type);
244
245        /* Get the challenge from the packet. */
246        if ((challenge = BN_new()) == NULL)
247                fatal("try_rsa_authentication: BN_new failed");
248        packet_get_bignum(challenge);
249        packet_check_eom();
250
251        debug("Received RSA challenge from server.");
252
253        /*
254         * If the key is not stored in external hardware, we have to
255         * load the private key.  Try first with empty passphrase; if it
256         * fails, ask for a passphrase.
257         */
258        if (public->flags & KEY_FLAG_EXT)
259                private = public;
260        else
261                private = key_load_private_type(KEY_RSA1, authfile, "", NULL);
262        if (private == NULL && !options.batch_mode) {
263                snprintf(buf, sizeof(buf),
264                    "Enter passphrase for RSA key '%.100s': ", comment);
265                for (i = 0; i < options.number_of_password_prompts; i++) {
266                        passphrase = read_passphrase(buf, 0);
267                        if (strcmp(passphrase, "") != 0) {
268                                private = key_load_private_type(KEY_RSA1,
269                                    authfile, passphrase, NULL);
270                                quit = 0;
271                        } else {
272                                debug2("no passphrase given, try next key");
273                                quit = 1;
274                        }
275                        memset(passphrase, 0, strlen(passphrase));
276                        xfree(passphrase);
277                        if (private != NULL || quit)
278                                break;
279                        debug2("bad passphrase given, try again...");
280                }
281        }
282        /* We no longer need the comment. */
283        xfree(comment);
284
285        if (private == NULL) {
286                if (!options.batch_mode)
287                        error("Bad passphrase.");
288
289                /* Send a dummy response packet to avoid protocol error. */
290                packet_start(SSH_CMSG_AUTH_RSA_RESPONSE);
291                for (i = 0; i < 16; i++)
292                        packet_put_char(0);
293                packet_send();
294                packet_write_wait();
295
296                /* Expect the server to reject it... */
297                packet_read_expect(SSH_SMSG_FAILURE);
298                BN_clear_free(challenge);
299                return 0;
300        }
301
302        /* Compute and send a response to the challenge. */
303        respond_to_rsa_challenge(challenge, private->rsa);
304
305        /* Destroy the private key unless it in external hardware. */
306        if (!(private->flags & KEY_FLAG_EXT))
307                key_free(private);
308
309        /* We no longer need the challenge. */
310        BN_clear_free(challenge);
311
312        /* Wait for response from the server. */
313        type = packet_read();
314        if (type == SSH_SMSG_SUCCESS) {
315                debug("RSA authentication accepted by server.");
316                return 1;
317        }
318        if (type != SSH_SMSG_FAILURE)
319                packet_disconnect("Protocol error waiting RSA auth response: %d", type);
320        debug("RSA authentication refused.");
321        return 0;
322}
323
324/*
325 * Tries to authenticate the user using combined rhosts or /etc/hosts.equiv
326 * authentication and RSA host authentication.
327 */
328static int
329try_rhosts_rsa_authentication(const char *local_user, Key * host_key)
330{
331        int type;
332        BIGNUM *challenge;
333
334        debug("Trying rhosts or /etc/hosts.equiv with RSA host authentication.");
335
336        /* Tell the server that we are willing to authenticate using this key. */
337        packet_start(SSH_CMSG_AUTH_RHOSTS_RSA);
338        packet_put_cstring(local_user);
339        packet_put_int(BN_num_bits(host_key->rsa->n));
340        packet_put_bignum(host_key->rsa->e);
341        packet_put_bignum(host_key->rsa->n);
342        packet_send();
343        packet_write_wait();
344
345        /* Wait for server's response. */
346        type = packet_read();
347
348        /* The server responds with failure if it doesn't admit our
349           .rhosts authentication or doesn't know our host key. */
350        if (type == SSH_SMSG_FAILURE) {
351                debug("Server refused our rhosts authentication or host key.");
352                return 0;
353        }
354        /* Otherwise, the server should respond with a challenge. */
355        if (type != SSH_SMSG_AUTH_RSA_CHALLENGE)
356                packet_disconnect("Protocol error during RSA authentication: %d", type);
357
358        /* Get the challenge from the packet. */
359        if ((challenge = BN_new()) == NULL)
360                fatal("try_rhosts_rsa_authentication: BN_new failed");
361        packet_get_bignum(challenge);
362        packet_check_eom();
363
364        debug("Received RSA challenge for host key from server.");
365
366        /* Compute a response to the challenge. */
367        respond_to_rsa_challenge(challenge, host_key->rsa);
368
369        /* We no longer need the challenge. */
370        BN_clear_free(challenge);
371
372        /* Wait for response from the server. */
373        type = packet_read();
374        if (type == SSH_SMSG_SUCCESS) {
375                debug("Rhosts or /etc/hosts.equiv with RSA host authentication accepted by server.");
376                return 1;
377        }
378        if (type != SSH_SMSG_FAILURE)
379                packet_disconnect("Protocol error waiting RSA auth response: %d", type);
380        debug("Rhosts or /etc/hosts.equiv with RSA host authentication refused.");
381        return 0;
382}
383
384#ifdef KRB4
385static int
386try_krb4_authentication(void)
387{
388        KTEXT_ST auth;          /* Kerberos data */
389        char *reply;
390        char inst[INST_SZ];
391        char *realm;
392        CREDENTIALS cred;
393        int r, type;
394        socklen_t slen;
395        Key_schedule schedule;
396        u_long checksum, cksum;
397        MSG_DAT msg_data;
398        struct sockaddr_in local, foreign;
399        struct stat st;
400
401        /* Don't do anything if we don't have any tickets. */
402        if (stat(tkt_string(), &st) < 0)
403                return 0;
404
405        strlcpy(inst, (char *)krb_get_phost(get_canonical_hostname(1)),
406            INST_SZ);
407
408        realm = (char *)krb_realmofhost(get_canonical_hostname(1));
409        if (!realm) {
410                debug("Kerberos v4: no realm for %s", get_canonical_hostname(1));
411                return 0;
412        }
413        /* This can really be anything. */
414        checksum = (u_long)getpid();
415
416        r = krb_mk_req(&auth, KRB4_SERVICE_NAME, inst, realm, checksum);
417        if (r != KSUCCESS) {
418                debug("Kerberos v4 krb_mk_req failed: %s", krb_err_txt[r]);
419                return 0;
420        }
421        /* Get session key to decrypt the server's reply with. */
422        r = krb_get_cred(KRB4_SERVICE_NAME, inst, realm, &cred);
423        if (r != KSUCCESS) {
424                debug("get_cred failed: %s", krb_err_txt[r]);
425                return 0;
426        }
427        des_key_sched((des_cblock *) cred.session, schedule);
428
429        /* Send authentication info to server. */
430        packet_start(SSH_CMSG_AUTH_KERBEROS);
431        packet_put_string((char *) auth.dat, auth.length);
432        packet_send();
433        packet_write_wait();
434
435        /* Zero the buffer. */
436        (void) memset(auth.dat, 0, MAX_KTXT_LEN);
437
438        slen = sizeof(local);
439        memset(&local, 0, sizeof(local));
440        if (getsockname(packet_get_connection_in(),
441            (struct sockaddr *)&local, &slen) < 0)
442                debug("getsockname failed: %s", strerror(errno));
443
444        slen = sizeof(foreign);
445        memset(&foreign, 0, sizeof(foreign));
446        if (getpeername(packet_get_connection_in(),
447            (struct sockaddr *)&foreign, &slen) < 0) {
448                debug("getpeername failed: %s", strerror(errno));
449                fatal_cleanup();
450        }
451        /* Get server reply. */
452        type = packet_read();
453        switch (type) {
454        case SSH_SMSG_FAILURE:
455                /* Should really be SSH_SMSG_AUTH_KERBEROS_FAILURE */
456                debug("Kerberos v4 authentication failed.");
457                return 0;
458                break;
459
460        case SSH_SMSG_AUTH_KERBEROS_RESPONSE:
461                /* SSH_SMSG_AUTH_KERBEROS_SUCCESS */
462                debug("Kerberos v4 authentication accepted.");
463
464                /* Get server's response. */
465                reply = packet_get_string((u_int *) &auth.length);
466                if (auth.length >= MAX_KTXT_LEN)
467                        fatal("Kerberos v4: Malformed response from server");
468                memcpy(auth.dat, reply, auth.length);
469                xfree(reply);
470
471                packet_check_eom();
472
473                /*
474                 * If his response isn't properly encrypted with the session
475                 * key, and the decrypted checksum fails to match, he's
476                 * bogus. Bail out.
477                 */
478                r = krb_rd_priv(auth.dat, auth.length, schedule, &cred.session,
479                    &foreign, &local, &msg_data);
480                if (r != KSUCCESS) {
481                        debug("Kerberos v4 krb_rd_priv failed: %s",
482                            krb_err_txt[r]);
483                        packet_disconnect("Kerberos v4 challenge failed!");
484                }
485                /* Fetch the (incremented) checksum that we supplied in the request. */
486                memcpy((char *)&cksum, (char *)msg_data.app_data,
487                    sizeof(cksum));
488                cksum = ntohl(cksum);
489
490                /* If it matches, we're golden. */
491                if (cksum == checksum + 1) {
492                        debug("Kerberos v4 challenge successful.");
493                        return 1;
494                } else
495                        packet_disconnect("Kerberos v4 challenge failed!");
496                break;
497
498        default:
499                packet_disconnect("Protocol error on Kerberos v4 response: %d", type);
500        }
501        return 0;
502}
503
504#endif /* KRB4 */
505
506#ifdef KRB5
507static int
508ssh1_krb5_common(krb5_context *context, krb5_auth_context *auth_context)
509{
510        int problem;
511
512        if (*context == NULL) {
513                problem = krb5_init_context(context);
514                if (problem) {
515                        debug("Kerberos v5: krb5_init_context failed");
516                        return problem;
517                }
518        }
519       
520        if (*auth_context == NULL) {
521                problem = krb5_auth_con_init(*context, auth_context);
522                if (problem) {
523                        debug("Kerberos v5: krb5_auth_con_init failed");
524                        return problem;
525                }
526        }
527
528#ifndef HEIMDAL
529        problem = krb5_auth_con_setflags(*context, *auth_context,
530                                         KRB5_AUTH_CONTEXT_RET_TIME);
531        if (problem) {
532                debug("Kerberos v5: krb5_auth_con_setflags failed");
533                return problem;
534        }                               
535#endif
536
537        return 0;
538
539}
540
541static int
542try_krb5_authentication(char *host, krb5_context *context, krb5_auth_context *auth_context)
543{
544        krb5_error_code problem;
545        const char *tkfile;
546        struct stat buf;
547        krb5_ccache ccache = NULL;
548        const char *remotehost;
549        krb5_data ap;
550        int type;
551        krb5_ap_rep_enc_part *reply = NULL;
552        int ret;
553        struct hostent *hp_static;
554        krb5_creds creds, *new_creds;
555        char **hostrealms;
556
557        memset(&ap, 0, sizeof(ap));
558
559        problem = ssh1_krb5_common(context, auth_context);
560        if (problem) {
561                ret = 0;
562                goto out;
563        }
564
565        tkfile = krb5_cc_default_name(*context);
566        if (strncmp(tkfile, "FILE:", 5) == 0)
567                tkfile += 5;
568
569        if (stat(tkfile, &buf) == 0 && getuid() != buf.st_uid) {
570                debug("Kerberos v5: could not get default ccache (permission denied).");
571                ret = 0;
572                goto out;
573        }
574
575        problem = krb5_cc_default(*context, &ccache);
576        if (problem) {
577                debug("Kerberos v5: krb5_cc_default failed: %s",
578                    krb5_get_err_text(*context, problem));
579                ret = 0;
580                goto out;
581        }
582
583        remotehost = get_canonical_hostname(1);
584
585        problem = krb5_mk_req(*context, auth_context, AP_OPTS_MUTUAL_REQUIRED,
586            "host", remotehost, NULL, ccache, &ap);
587        if (problem) {
588                int state = -1; /* error but nothing to do */
589                char *canonhost = NULL;
590
591                debug("Kerberos v5: krb5_mk_req failed: %s",
592                      krb5_get_err_text(*context, problem));
593
594                /* Now try to use the original host directly.  This handles
595                 * the case where you have forward DNS but not reverse DNS.
596                 * This is a "best effort" attempt to find the requested host
597                 * and use it.
598                 */
599                do {
600                  hp_static = gethostbyname(host);
601                  if (!hp_static)
602                    break;
603                 
604                  canonhost = xstrdup (hp_static->h_name);
605                  memset((char *)&creds, 0, sizeof(creds));
606                  problem = krb5_get_host_realm (*context, canonhost, &hostrealms);
607                  if (problem) {
608                    debug("Kerberos V5: error while obtaining host realm: %.100s.",
609                          krb5_get_err_text(*context, problem));
610                    break;
611                  }
612                 
613                  /* Note, this assumes that hostrealm[0] is valid. */
614                  problem = krb5_build_principal (*context, &creds.server,
615                                                  strlen(hostrealms[0]),
616                                                  hostrealms[0],
617                                                  "host", canonhost, NULL);
618                  if (problem) {
619                    debug("Kerberos V5: error while constructing service name: %.100s.",
620                          krb5_get_err_text(*context, problem));
621                    krb5_free_host_realm (*context, hostrealms);
622                    break;
623                  }
624                  krb5_free_host_realm (*context, hostrealms);
625                 
626                  state = 1; /* need to free the creds contents */
627                  problem = krb5_cc_get_principal(*context, ccache, &creds.client);
628                  if (problem) {
629                    debug("Kerberos V5: failure on principal (%.100s).",
630                          krb5_get_err_text(*context, problem));
631                    break;
632                  }
633                 
634                  problem = krb5_get_credentials(*context, 0,
635                                                 ccache, &creds, &new_creds);
636                  if (problem) {
637                    char *name;
638                    krb5_unparse_name (*context, creds.server, &name);
639                    debug("Kerberos V5: failure on credentials for %s (%.100s)."
640                          "\n\t(%s)",
641                          canonhost, krb5_get_err_text(*context, problem), name);
642                    xfree(name);
643                    break;
644                  }
645                 
646                  problem = krb5_mk_req_extended(*context, auth_context,
647                                                 AP_OPTS_MUTUAL_REQUIRED,
648                                                 NULL, new_creds, &ap);
649                 
650                  krb5_free_cred_contents(*context, new_creds);
651                 
652                  if (problem) {
653                    debug("Kerberos V5: failed krb5_mk_req_extended (%.100s)",
654                          krb5_get_err_text(*context, problem));
655                    break;
656                  }
657                 
658                  /* If we got here, then we've succeeded */
659                  state = 0;    /* SUCCESS */
660                } while (0);
661               
662                if (canonhost)
663                  xfree (canonhost);
664               
665                if (state >= 0)
666                  krb5_free_cred_contents(*context, &creds);
667               
668                /* Deal with errors */
669                if (state) {
670                  ret = 0;
671                  goto out;
672                }
673        }
674
675        packet_start(SSH_CMSG_AUTH_KERBEROS);
676        packet_put_string((char *) ap.data, ap.length);
677        packet_send();
678        packet_write_wait();
679
680        xfree(ap.data);
681        ap.length = 0;
682
683        type = packet_read();
684        switch (type) {
685        case SSH_SMSG_FAILURE:
686                /* Should really be SSH_SMSG_AUTH_KERBEROS_FAILURE */
687                debug("Kerberos v5 authentication failed.");
688                ret = 0;
689                break;
690
691        case SSH_SMSG_AUTH_KERBEROS_RESPONSE:
692                /* SSH_SMSG_AUTH_KERBEROS_SUCCESS */
693                debug("Kerberos v5 authentication accepted.");
694
695                /* Get server's response. */
696                ap.data = packet_get_string((unsigned int *) &ap.length);
697                packet_check_eom();
698                /* XXX je to dobre? */
699
700                problem = krb5_rd_rep(*context, *auth_context, &ap, &reply);
701                if (problem) {
702                        ret = 0;
703                }
704                ret = 1;
705                break;
706
707        default:
708                packet_disconnect("Protocol error on Kerberos v5 response: %d",
709                    type);
710                ret = 0;
711                break;
712
713        }
714
715 out:
716        if (ccache != NULL)
717                krb5_cc_close(*context, ccache);
718        if (reply != NULL)
719                krb5_free_ap_rep_enc_part(*context, reply);
720        if (ap.length > 0)
721#ifdef HEIMDAL
722                krb5_data_free(&ap);
723#else
724                krb5_free_data_contents(*context, &ap);
725#endif
726
727        return (ret);
728}
729
730static void
731send_krb5_tgt(krb5_context context, krb5_auth_context auth_context)
732{
733        int fd, type;
734        krb5_error_code problem;
735        krb5_data outbuf;
736        krb5_ccache ccache = NULL;
737        krb5_creds creds;
738#ifdef HEIMDAL
739        krb5_kdc_flags flags;
740#else
741        int forwardable;
742#endif
743        const char *remotehost;
744
745        memset(&creds, 0, sizeof(creds));
746        memset(&outbuf, 0, sizeof(outbuf));
747
748        problem = ssh1_krb5_common(&context, &auth_context);
749        if (problem)
750                goto out;
751
752        fd = packet_get_connection_in();
753
754#ifdef HEIMDAL
755        problem = krb5_auth_con_setaddrs_from_fd(context, auth_context, &fd);
756#else
757        problem = krb5_auth_con_genaddrs(context, auth_context, fd,
758                        KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR |
759                        KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR);
760#endif
761        if (problem)
762                goto out;
763
764        problem = krb5_cc_default(context, &ccache);
765        if (problem)
766                goto out;
767
768        problem = krb5_cc_get_principal(context, ccache, &creds.client);
769        if (problem)
770                goto out;
771
772        remotehost = get_canonical_hostname(1);
773       
774#ifdef HEIMDAL
775        problem = krb5_build_principal(context, &creds.server,
776            strlen(creds.client->realm), creds.client->realm,
777            "krbtgt", creds.client->realm, NULL);
778#else
779        problem = krb5_build_principal(context, &creds.server,
780            creds.client->realm.length, creds.client->realm.data,
781            "host", remotehost, NULL);
782#endif
783        if (problem)
784                goto out;
785
786        creds.times.endtime = 0;
787
788#ifdef HEIMDAL
789        flags.i = 0;
790        flags.b.forwarded = 1;
791        flags.b.forwardable = krb5_config_get_bool(context,  NULL,
792            "libdefaults", "forwardable", NULL);
793        problem = krb5_get_forwarded_creds(context, auth_context,
794            ccache, flags.i, remotehost, &creds, &outbuf);
795#else
796        forwardable = 1;
797        problem = krb5_fwd_tgt_creds(context, auth_context, remotehost,
798            creds.client, creds.server, ccache, forwardable, &outbuf);
799#endif
800
801        if (problem)
802                goto out;
803
804        packet_start(SSH_CMSG_HAVE_KERBEROS_TGT);
805        packet_put_string((char *)outbuf.data, outbuf.length);
806        packet_send();
807        packet_write_wait();
808
809        type = packet_read();
810
811        if (type == SSH_SMSG_SUCCESS) {
812                char *pname;
813
814                krb5_unparse_name(context, creds.client, &pname);
815                debug("Kerberos v5 TGT forwarded (%s).", pname);
816                xfree(pname);
817        } else
818                debug("Kerberos v5 TGT forwarding failed.");
819
820        return;
821
822 out:
823        if (problem)
824                debug("Kerberos v5 TGT forwarding failed: %s",
825                    krb5_get_err_text(context, problem));
826        if (creds.client)
827                krb5_free_principal(context, creds.client);
828        if (creds.server)
829                krb5_free_principal(context, creds.server);
830        if (ccache)
831                krb5_cc_close(context, ccache);
832        if (outbuf.data)
833                xfree(outbuf.data);
834}
835#endif /* KRB5 */
836
837#ifdef AFS
838static void
839send_krb4_tgt(void)
840{
841        CREDENTIALS *creds;
842        struct stat st;
843        char buffer[4096], pname[ANAME_SZ], pinst[INST_SZ], prealm[REALM_SZ];
844        int problem, type;
845
846        /* Don't do anything if we don't have any tickets. */
847        if (stat(tkt_string(), &st) < 0)
848                return;
849
850        creds = xmalloc(sizeof(*creds));
851
852        problem = krb_get_tf_fullname(TKT_FILE, pname, pinst, prealm);
853        if (problem)
854                goto out;
855
856        problem = krb_get_cred("krbtgt", prealm, prealm, creds);
857        if (problem)
858                goto out;
859
860        if (time(0) > krb_life_to_time(creds->issue_date, creds->lifetime)) {
861                problem = RD_AP_EXP;
862                goto out;
863        }
864        creds_to_radix(creds, (u_char *)buffer, sizeof(buffer));
865
866        packet_start(SSH_CMSG_HAVE_KERBEROS_TGT);
867        packet_put_cstring(buffer);
868        packet_send();
869        packet_write_wait();
870
871        type = packet_read();
872
873        if (type == SSH_SMSG_SUCCESS)
874                debug("Kerberos v4 TGT forwarded (%s%s%s@%s).",
875                    creds->pname, creds->pinst[0] ? "." : "",
876                    creds->pinst, creds->realm);
877        else
878                debug("Kerberos v4 TGT rejected.");
879
880        xfree(creds);
881        return;
882
883 out:
884        debug("Kerberos v4 TGT passing failed: %s", krb_err_txt[problem]);
885        xfree(creds);
886}
887
888static void
889send_afs_tokens(void)
890{
891        CREDENTIALS creds;
892        struct ViceIoctl parms;
893        struct ClearToken ct;
894        int i, type, len;
895        char buf[2048], *p, *server_cell;
896        char buffer[8192];
897
898        /* Move over ktc_GetToken, here's something leaner. */
899        for (i = 0; i < 100; i++) {     /* just in case */
900                parms.in = (char *) &i;
901                parms.in_size = sizeof(i);
902                parms.out = buf;
903                parms.out_size = sizeof(buf);
904                if (k_pioctl(0, VIOCGETTOK, &parms, 0) != 0)
905                        break;
906                p = buf;
907
908                /* Get secret token. */
909                memcpy(&creds.ticket_st.length, p, sizeof(u_int));
910                if (creds.ticket_st.length > MAX_KTXT_LEN)
911                        break;
912                p += sizeof(u_int);
913                memcpy(creds.ticket_st.dat, p, creds.ticket_st.length);
914                p += creds.ticket_st.length;
915
916                /* Get clear token. */
917                memcpy(&len, p, sizeof(len));
918                if (len != sizeof(struct ClearToken))
919                        break;
920                p += sizeof(len);
921                memcpy(&ct, p, len);
922                p += len;
923                p += sizeof(len);       /* primary flag */
924                server_cell = p;
925
926                /* Flesh out our credentials. */
927                strlcpy(creds.service, "afs", sizeof(creds.service));
928                creds.instance[0] = '\0';
929                strlcpy(creds.realm, server_cell, REALM_SZ);
930                memcpy(creds.session, ct.HandShakeKey, DES_KEY_SZ);
931                creds.issue_date = ct.BeginTimestamp;
932                creds.lifetime = krb_time_to_life(creds.issue_date,
933                    ct.EndTimestamp);
934                creds.kvno = ct.AuthHandle;
935                snprintf(creds.pname, sizeof(creds.pname), "AFS ID %d", ct.ViceId);
936                creds.pinst[0] = '\0';
937
938                /* Encode token, ship it off. */
939                if (creds_to_radix(&creds, (u_char *)buffer,
940                    sizeof(buffer)) <= 0)
941                        break;
942                packet_start(SSH_CMSG_HAVE_AFS_TOKEN);
943                packet_put_cstring(buffer);
944                packet_send();
945                packet_write_wait();
946
947                /* Roger, Roger. Clearance, Clarence. What's your vector,
948                   Victor? */
949                type = packet_read();
950
951                if (type == SSH_SMSG_FAILURE)
952                        debug("AFS token for cell %s rejected.", server_cell);
953                else if (type != SSH_SMSG_SUCCESS)
954                        packet_disconnect("Protocol error on AFS token response: %d", type);
955        }
956}
957
958#endif /* AFS */
959
960/*
961 * Tries to authenticate with any string-based challenge/response system.
962 * Note that the client code is not tied to s/key or TIS.
963 */
964static int
965try_challenge_response_authentication(void)
966{
967        int type, i;
968        u_int clen;
969        char prompt[1024];
970        char *challenge, *response;
971
972        debug("Doing challenge response authentication.");
973
974        for (i = 0; i < options.number_of_password_prompts; i++) {
975                /* request a challenge */
976                packet_start(SSH_CMSG_AUTH_TIS);
977                packet_send();
978                packet_write_wait();
979
980                type = packet_read();
981                if (type != SSH_SMSG_FAILURE &&
982                    type != SSH_SMSG_AUTH_TIS_CHALLENGE) {
983                        packet_disconnect("Protocol error: got %d in response "
984                            "to SSH_CMSG_AUTH_TIS", type);
985                }
986                if (type != SSH_SMSG_AUTH_TIS_CHALLENGE) {
987                        debug("No challenge.");
988                        return 0;
989                }
990                challenge = packet_get_string(&clen);
991                packet_check_eom();
992                snprintf(prompt, sizeof prompt, "%s%s", challenge,
993                    strchr(challenge, '\n') ? "" : "\nResponse: ");
994                xfree(challenge);
995                if (i != 0)
996                        error("Permission denied, please try again.");
997                if (options.cipher == SSH_CIPHER_NONE)
998                        log("WARNING: Encryption is disabled! "
999                            "Response will be transmitted in clear text.");
1000                response = read_passphrase(prompt, 0);
1001                if (strcmp(response, "") == 0) {
1002                        xfree(response);
1003                        break;
1004                }
1005                packet_start(SSH_CMSG_AUTH_TIS_RESPONSE);
1006                ssh_put_password(response);
1007                memset(response, 0, strlen(response));
1008                xfree(response);
1009                packet_send();
1010                packet_write_wait();
1011                type = packet_read();
1012                if (type == SSH_SMSG_SUCCESS)
1013                        return 1;
1014                if (type != SSH_SMSG_FAILURE)
1015                        packet_disconnect("Protocol error: got %d in response "
1016                            "to SSH_CMSG_AUTH_TIS_RESPONSE", type);
1017        }
1018        /* failure */
1019        return 0;
1020}
1021
1022/*
1023 * Tries to authenticate with plain passwd authentication.
1024 */
1025static int
1026try_password_authentication(char *prompt)
1027{
1028        int type, i;
1029        char *password;
1030
1031        debug("Doing password authentication.");
1032        if (options.cipher == SSH_CIPHER_NONE)
1033                log("WARNING: Encryption is disabled! Password will be transmitted in clear text.");
1034        for (i = 0; i < options.number_of_password_prompts; i++) {
1035                if (i != 0)
1036                        error("Permission denied, please try again.");
1037                password = read_passphrase(prompt, 0);
1038                packet_start(SSH_CMSG_AUTH_PASSWORD);
1039                ssh_put_password(password);
1040                memset(password, 0, strlen(password));
1041                xfree(password);
1042                packet_send();
1043                packet_write_wait();
1044
1045                type = packet_read();
1046                if (type == SSH_SMSG_SUCCESS)
1047                        return 1;
1048                if (type != SSH_SMSG_FAILURE)
1049                        packet_disconnect("Protocol error: got %d in response to passwd auth", type);
1050        }
1051        /* failure */
1052        return 0;
1053}
1054
1055/*
1056 * SSH1 key exchange
1057 */
1058void
1059ssh_kex(char *host, struct sockaddr *hostaddr)
1060{
1061        int i;
1062        BIGNUM *key;
1063        Key *host_key, *server_key;
1064        int bits, rbits;
1065        int ssh_cipher_default = SSH_CIPHER_3DES;
1066        u_char session_key[SSH_SESSION_KEY_LENGTH];
1067        u_char cookie[8];
1068        u_int supported_ciphers;
1069        u_int server_flags, client_flags;
1070        u_int32_t rand = 0;
1071
1072        debug("Waiting for server public key.");
1073
1074        /* Wait for a public key packet from the server. */
1075        packet_read_expect(SSH_SMSG_PUBLIC_KEY);
1076
1077        /* Get cookie from the packet. */
1078        for (i = 0; i < 8; i++)
1079                cookie[i] = packet_get_char();
1080
1081        /* Get the public key. */
1082        server_key = key_new(KEY_RSA1);
1083        bits = packet_get_int();
1084        packet_get_bignum(server_key->rsa->e);
1085        packet_get_bignum(server_key->rsa->n);
1086
1087        rbits = BN_num_bits(server_key->rsa->n);
1088        if (bits != rbits) {
1089                log("Warning: Server lies about size of server public key: "
1090                    "actual size is %d bits vs. announced %d.", rbits, bits);
1091                log("Warning: This may be due to an old implementation of ssh.");
1092        }
1093        /* Get the host key. */
1094        host_key = key_new(KEY_RSA1);
1095        bits = packet_get_int();
1096        packet_get_bignum(host_key->rsa->e);
1097        packet_get_bignum(host_key->rsa->n);
1098
1099        rbits = BN_num_bits(host_key->rsa->n);
1100        if (bits != rbits) {
1101                log("Warning: Server lies about size of server host key: "
1102                    "actual size is %d bits vs. announced %d.", rbits, bits);
1103                log("Warning: This may be due to an old implementation of ssh.");
1104        }
1105
1106        /* Get protocol flags. */
1107        server_flags = packet_get_int();
1108        packet_set_protocol_flags(server_flags);
1109
1110        supported_ciphers = packet_get_int();
1111        supported_authentications = packet_get_int();
1112        packet_check_eom();
1113
1114        debug("Received server public key (%d bits) and host key (%d bits).",
1115            BN_num_bits(server_key->rsa->n), BN_num_bits(host_key->rsa->n));
1116
1117        if (verify_host_key(host, hostaddr, host_key) == -1)
1118                fatal("Host key verification failed.");
1119
1120        client_flags = SSH_PROTOFLAG_SCREEN_NUMBER | SSH_PROTOFLAG_HOST_IN_FWD_OPEN;
1121
1122        compute_session_id(session_id, cookie, host_key->rsa->n, server_key->rsa->n);
1123
1124        /* Generate a session key. */
1125        arc4random_stir();
1126
1127        /*
1128         * Generate an encryption key for the session.   The key is a 256 bit
1129         * random number, interpreted as a 32-byte key, with the least
1130         * significant 8 bits being the first byte of the key.
1131         */
1132        for (i = 0; i < 32; i++) {
1133                if (i % 4 == 0)
1134                        rand = arc4random();
1135                session_key[i] = rand & 0xff;
1136                rand >>= 8;
1137        }
1138
1139        /*
1140         * According to the protocol spec, the first byte of the session key
1141         * is the highest byte of the integer.  The session key is xored with
1142         * the first 16 bytes of the session id.
1143         */
1144        if ((key = BN_new()) == NULL)
1145                fatal("respond_to_rsa_challenge: BN_new failed");
1146        BN_set_word(key, 0);
1147        for (i = 0; i < SSH_SESSION_KEY_LENGTH; i++) {
1148                BN_lshift(key, key, 8);
1149                if (i < 16)
1150                        BN_add_word(key, session_key[i] ^ session_id[i]);
1151                else
1152                        BN_add_word(key, session_key[i]);
1153        }
1154
1155        /*
1156         * Encrypt the integer using the public key and host key of the
1157         * server (key with smaller modulus first).
1158         */
1159        if (BN_cmp(server_key->rsa->n, host_key->rsa->n) < 0) {
1160                /* Public key has smaller modulus. */
1161                if (BN_num_bits(host_key->rsa->n) <
1162                    BN_num_bits(server_key->rsa->n) + SSH_KEY_BITS_RESERVED) {
1163                        fatal("respond_to_rsa_challenge: host_key %d < server_key %d + "
1164                            "SSH_KEY_BITS_RESERVED %d",
1165                            BN_num_bits(host_key->rsa->n),
1166                            BN_num_bits(server_key->rsa->n),
1167                            SSH_KEY_BITS_RESERVED);
1168                }
1169                rsa_public_encrypt(key, key, server_key->rsa);
1170                rsa_public_encrypt(key, key, host_key->rsa);
1171        } else {
1172                /* Host key has smaller modulus (or they are equal). */
1173                if (BN_num_bits(server_key->rsa->n) <
1174                    BN_num_bits(host_key->rsa->n) + SSH_KEY_BITS_RESERVED) {
1175                        fatal("respond_to_rsa_challenge: server_key %d < host_key %d + "
1176                            "SSH_KEY_BITS_RESERVED %d",
1177                            BN_num_bits(server_key->rsa->n),
1178                            BN_num_bits(host_key->rsa->n),
1179                            SSH_KEY_BITS_RESERVED);
1180                }
1181                rsa_public_encrypt(key, key, host_key->rsa);
1182                rsa_public_encrypt(key, key, server_key->rsa);
1183        }
1184
1185        /* Destroy the public keys since we no longer need them. */
1186        key_free(server_key);
1187        key_free(host_key);
1188
1189        if (options.cipher == SSH_CIPHER_NOT_SET) {
1190                if (cipher_mask_ssh1(1) & supported_ciphers & (1 << ssh_cipher_default))
1191                        options.cipher = ssh_cipher_default;
1192        } else if (options.cipher == SSH_CIPHER_ILLEGAL ||
1193            !(cipher_mask_ssh1(1) & (1 << options.cipher))) {
1194                log("No valid SSH1 cipher, using %.100s instead.",
1195                    cipher_name(ssh_cipher_default));
1196                options.cipher = ssh_cipher_default;
1197        }
1198        /* Check that the selected cipher is supported. */
1199        if (!(supported_ciphers & (1 << options.cipher)))
1200                fatal("Selected cipher type %.100s not supported by server.",
1201                    cipher_name(options.cipher));
1202
1203        debug("Encryption type: %.100s", cipher_name(options.cipher));
1204
1205        /* Send the encrypted session key to the server. */
1206        packet_start(SSH_CMSG_SESSION_KEY);
1207        packet_put_char(options.cipher);
1208
1209        /* Send the cookie back to the server. */
1210        for (i = 0; i < 8; i++)
1211                packet_put_char(cookie[i]);
1212
1213        /* Send and destroy the encrypted encryption key integer. */
1214        packet_put_bignum(key);
1215        BN_clear_free(key);
1216
1217        /* Send protocol flags. */
1218        packet_put_int(client_flags);
1219
1220        /* Send the packet now. */
1221        packet_send();
1222        packet_write_wait();
1223
1224        debug("Sent encrypted session key.");
1225
1226        /* Set the encryption key. */
1227        packet_set_encryption_key(session_key, SSH_SESSION_KEY_LENGTH, options.cipher);
1228
1229        /* We will no longer need the session key here.  Destroy any extra copies. */
1230        memset(session_key, 0, sizeof(session_key));
1231
1232        /*
1233         * Expect a success message from the server.  Note that this message
1234         * will be received in encrypted form.
1235         */
1236        packet_read_expect(SSH_SMSG_SUCCESS);
1237
1238        debug("Received encrypted confirmation.");
1239}
1240
1241/*
1242 * Authenticate user
1243 */
1244void
1245ssh_userauth1(const char *local_user, const char *server_user, char *host,
1246    Sensitive *sensitive)
1247{
1248#ifdef KRB5
1249        krb5_context context = NULL;
1250        krb5_auth_context auth_context = NULL;
1251#endif
1252        int i, type;
1253
1254        if (supported_authentications == 0)
1255                fatal("ssh_userauth1: server supports no auth methods");
1256
1257        /* Send the name of the user to log in as on the server. */
1258        packet_start(SSH_CMSG_USER);
1259        packet_put_cstring(server_user);
1260        packet_send();
1261        packet_write_wait();
1262
1263        /*
1264         * The server should respond with success if no authentication is
1265         * needed (the user has no password).  Otherwise the server responds
1266         * with failure.
1267         */
1268        type = packet_read();
1269
1270        /* check whether the connection was accepted without authentication. */
1271        if (type == SSH_SMSG_SUCCESS)
1272                goto success;
1273        if (type != SSH_SMSG_FAILURE)
1274                packet_disconnect("Protocol error: got %d in response to SSH_CMSG_USER", type);
1275
1276#ifdef KRB5
1277        /* Try Kerberos v5 TGT passing, for ssh.com */
1278        if ((supported_authentications & (1 << SSH_PASS_KERBEROS_TGT)) &&
1279            options.kerberos_tgt_passing && (datafellows & SSH_BUG_K5USER)) {
1280                debug("Trying Kerberos v5 TGT forwarding (compatibility).");
1281                if (options.cipher == SSH_CIPHER_NONE)
1282                        log("WARNING: Encryption is disabled! Ticket will be transmitted in the clear!");
1283                send_krb5_tgt(context, auth_context);
1284        }
1285
1286        if ((supported_authentications & (1 << SSH_AUTH_KERBEROS)) &&
1287            options.kerberos_authentication) {
1288                debug("Trying Kerberos v5 authentication.");
1289
1290                if (try_krb5_authentication(host, &context, &auth_context)) {
1291                        type = packet_read();
1292                        if (type == SSH_SMSG_SUCCESS)
1293                                goto success;
1294                        if (type != SSH_SMSG_FAILURE)
1295                                packet_disconnect("Protocol error: got %d in response to Kerberos v5 auth", type);
1296                }
1297        }
1298#endif /* KRB5 */
1299
1300#ifdef KRB4
1301        if ((supported_authentications & (1 << SSH_AUTH_KERBEROS)) &&
1302            options.kerberos_authentication) {
1303                debug("Trying Kerberos v4 authentication.");
1304
1305                if (try_krb4_authentication()) {
1306                        type = packet_read();
1307                        if (type == SSH_SMSG_SUCCESS)
1308                                goto success;
1309                        if (type != SSH_SMSG_FAILURE)
1310                                packet_disconnect("Protocol error: got %d in response to Kerberos v4 auth", type);
1311                }
1312        }
1313#endif /* KRB4 */
1314
1315        /*
1316         * Use rhosts authentication if running in privileged socket and we
1317         * do not wish to remain anonymous.
1318         */
1319        if ((supported_authentications & (1 << SSH_AUTH_RHOSTS)) &&
1320            options.rhosts_authentication) {
1321                debug("Trying rhosts authentication.");
1322                packet_start(SSH_CMSG_AUTH_RHOSTS);
1323                packet_put_cstring(local_user);
1324                packet_send();
1325                packet_write_wait();
1326
1327                /* The server should respond with success or failure. */
1328                type = packet_read();
1329                if (type == SSH_SMSG_SUCCESS)
1330                        goto success;
1331                if (type != SSH_SMSG_FAILURE)
1332                        packet_disconnect("Protocol error: got %d in response to rhosts auth",
1333                                          type);
1334        }
1335        /*
1336         * Try .rhosts or /etc/hosts.equiv authentication with RSA host
1337         * authentication.
1338         */
1339        if ((supported_authentications & (1 << SSH_AUTH_RHOSTS_RSA)) &&
1340            options.rhosts_rsa_authentication) {
1341                for (i = 0; i < sensitive->nkeys; i++) {
1342                        if (sensitive->keys[i] != NULL &&
1343                            sensitive->keys[i]->type == KEY_RSA1 &&
1344                            try_rhosts_rsa_authentication(local_user,
1345                            sensitive->keys[i]))
1346                                goto success;
1347                }
1348        }
1349        /* Try RSA authentication if the server supports it. */
1350        if ((supported_authentications & (1 << SSH_AUTH_RSA)) &&
1351            options.rsa_authentication) {
1352                /*
1353                 * Try RSA authentication using the authentication agent. The
1354                 * agent is tried first because no passphrase is needed for
1355                 * it, whereas identity files may require passphrases.
1356                 */
1357                if (try_agent_authentication())
1358                        goto success;
1359
1360                /* Try RSA authentication for each identity. */
1361                for (i = 0; i < options.num_identity_files; i++)
1362                        if (options.identity_keys[i] != NULL &&
1363                            options.identity_keys[i]->type == KEY_RSA1 &&
1364                            try_rsa_authentication(i))
1365                                goto success;
1366        }
1367        /* Try challenge response authentication if the server supports it. */
1368        if ((supported_authentications & (1 << SSH_AUTH_TIS)) &&
1369            options.challenge_response_authentication && !options.batch_mode) {
1370                if (try_challenge_response_authentication())
1371                        goto success;
1372        }
1373        /* Try password authentication if the server supports it. */
1374        if ((supported_authentications & (1 << SSH_AUTH_PASSWORD)) &&
1375            options.password_authentication && !options.batch_mode) {
1376                char prompt[80];
1377
1378                snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password: ",
1379                    server_user, host);
1380                if (try_password_authentication(prompt))
1381                        goto success;
1382        }
1383        /* All authentication methods have failed.  Exit with an error message. */
1384        fatal("Permission denied.");
1385        /* NOTREACHED */
1386
1387 success:
1388#ifdef KRB5
1389        /* Try Kerberos v5 TGT passing. */
1390        if ((supported_authentications & (1 << SSH_PASS_KERBEROS_TGT)) &&
1391            options.kerberos_tgt_passing && context && auth_context) {
1392                if (options.cipher == SSH_CIPHER_NONE)
1393                        log("WARNING: Encryption is disabled! Ticket will be transmitted in the clear!");
1394                send_krb5_tgt(context, auth_context);
1395        }
1396        if (auth_context)
1397                krb5_auth_con_free(context, auth_context);
1398        if (context)
1399                krb5_free_context(context);
1400#endif
1401
1402#ifdef AFS
1403        /* Try Kerberos v4 TGT passing if the server supports it. */
1404        if ((supported_authentications & (1 << SSH_PASS_KERBEROS_TGT)) &&
1405            options.kerberos_tgt_passing) {
1406                if (options.cipher == SSH_CIPHER_NONE)
1407                        log("WARNING: Encryption is disabled! Ticket will be transmitted in the clear!");
1408                send_krb4_tgt();
1409        }
1410        /* Try AFS token passing if the server supports it. */
1411        if ((supported_authentications & (1 << SSH_PASS_AFS_TOKEN)) &&
1412            options.afs_token_passing && k_hasafs()) {
1413                if (options.cipher == SSH_CIPHER_NONE)
1414                        log("WARNING: Encryption is disabled! Token will be transmitted in the clear!");
1415                send_afs_tokens();
1416        }
1417#endif /* AFS */
1418
1419        return; /* need statement after label */
1420}
Note: See TracBrowser for help on using the repository browser.