[BACK]Return to sshconnect1.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / ssh

Diff for /src/usr.bin/ssh/Attic/sshconnect1.c between version 1.53 and 1.54

version 1.53, 2003/04/08 20:21:29 version 1.54, 2003/07/22 13:35:22
Line 18 
Line 18 
 #include <openssl/bn.h>  #include <openssl/bn.h>
 #include <openssl/md5.h>  #include <openssl/md5.h>
   
 #ifdef KRB4  
 #include <krb.h>  
 #endif  
 #ifdef KRB5  #ifdef KRB5
 #include <krb5.h>  #include <krb5.h>
 #endif  #endif
 #ifdef AFS  
 #include <kafs.h>  
 #include "radix.h"  
 #endif  
   
 #include "ssh.h"  #include "ssh.h"
 #include "ssh1.h"  #include "ssh1.h"
Line 377 
Line 370 
         return 0;          return 0;
 }  }
   
 #ifdef KRB4  
 static int  
 try_krb4_authentication(void)  
 {  
         KTEXT_ST auth;          /* Kerberos data */  
         char *reply;  
         char inst[INST_SZ];  
         char *realm;  
         CREDENTIALS cred;  
         int r, type;  
         socklen_t slen;  
         Key_schedule schedule;  
         u_long checksum, cksum;  
         MSG_DAT msg_data;  
         struct sockaddr_in local, foreign;  
         struct stat st;  
   
         /* Don't do anything if we don't have any tickets. */  
         if (stat(tkt_string(), &st) < 0)  
                 return 0;  
   
         strlcpy(inst, (char *)krb_get_phost(get_canonical_hostname(1)),  
             INST_SZ);  
   
         realm = (char *)krb_realmofhost(get_canonical_hostname(1));  
         if (!realm) {  
                 debug("Kerberos v4: no realm for %s", get_canonical_hostname(1));  
                 return 0;  
         }  
         /* This can really be anything. */  
         checksum = (u_long)getpid();  
   
         r = krb_mk_req(&auth, KRB4_SERVICE_NAME, inst, realm, checksum);  
         if (r != KSUCCESS) {  
                 debug("Kerberos v4 krb_mk_req failed: %s", krb_err_txt[r]);  
                 return 0;  
         }  
         /* Get session key to decrypt the server's reply with. */  
         r = krb_get_cred(KRB4_SERVICE_NAME, inst, realm, &cred);  
         if (r != KSUCCESS) {  
                 debug("get_cred failed: %s", krb_err_txt[r]);  
                 return 0;  
         }  
         des_key_sched((des_cblock *) cred.session, schedule);  
   
         /* Send authentication info to server. */  
         packet_start(SSH_CMSG_AUTH_KERBEROS);  
         packet_put_string((char *) auth.dat, auth.length);  
         packet_send();  
         packet_write_wait();  
   
         /* Zero the buffer. */  
         (void) memset(auth.dat, 0, MAX_KTXT_LEN);  
   
         slen = sizeof(local);  
         memset(&local, 0, sizeof(local));  
         if (getsockname(packet_get_connection_in(),  
             (struct sockaddr *)&local, &slen) < 0)  
                 debug("getsockname failed: %s", strerror(errno));  
   
         slen = sizeof(foreign);  
         memset(&foreign, 0, sizeof(foreign));  
         if (getpeername(packet_get_connection_in(),  
             (struct sockaddr *)&foreign, &slen) < 0) {  
                 debug("getpeername failed: %s", strerror(errno));  
                 fatal_cleanup();  
         }  
         /* Get server reply. */  
         type = packet_read();  
         switch (type) {  
         case SSH_SMSG_FAILURE:  
                 /* Should really be SSH_SMSG_AUTH_KERBEROS_FAILURE */  
                 debug("Kerberos v4 authentication failed.");  
                 return 0;  
                 break;  
   
         case SSH_SMSG_AUTH_KERBEROS_RESPONSE:  
                 /* SSH_SMSG_AUTH_KERBEROS_SUCCESS */  
                 debug("Kerberos v4 authentication accepted.");  
   
                 /* Get server's response. */  
                 reply = packet_get_string((u_int *) &auth.length);  
                 if (auth.length >= MAX_KTXT_LEN)  
                         fatal("Kerberos v4: Malformed response from server");  
                 memcpy(auth.dat, reply, auth.length);  
                 xfree(reply);  
   
                 packet_check_eom();  
   
                 /*  
                  * If his response isn't properly encrypted with the session  
                  * key, and the decrypted checksum fails to match, he's  
                  * bogus. Bail out.  
                  */  
                 r = krb_rd_priv(auth.dat, auth.length, schedule, &cred.session,  
                     &foreign, &local, &msg_data);  
                 if (r != KSUCCESS) {  
                         debug("Kerberos v4 krb_rd_priv failed: %s",  
                             krb_err_txt[r]);  
                         packet_disconnect("Kerberos v4 challenge failed!");  
                 }  
                 /* Fetch the (incremented) checksum that we supplied in the request. */  
                 memcpy((char *)&cksum, (char *)msg_data.app_data,  
                     sizeof(cksum));  
                 cksum = ntohl(cksum);  
   
                 /* If it matches, we're golden. */  
                 if (cksum == checksum + 1) {  
                         debug("Kerberos v4 challenge successful.");  
                         return 1;  
                 } else  
                         packet_disconnect("Kerberos v4 challenge failed!");  
                 break;  
   
         default:  
                 packet_disconnect("Protocol error on Kerberos v4 response: %d", type);  
         }  
         return 0;  
 }  
   
 #endif /* KRB4 */  
   
 #ifdef KRB5  #ifdef KRB5
 static int  static int
 try_krb5_authentication(krb5_context *context, krb5_auth_context *auth_context)  try_krb5_authentication(krb5_context *context, krb5_auth_context *auth_context)
Line 683 
Line 554 
 }  }
 #endif /* KRB5 */  #endif /* KRB5 */
   
 #ifdef AFS  
 static void  
 send_krb4_tgt(void)  
 {  
         CREDENTIALS *creds;  
         struct stat st;  
         char buffer[4096], pname[ANAME_SZ], pinst[INST_SZ], prealm[REALM_SZ];  
         int problem, type;  
   
         /* Don't do anything if we don't have any tickets. */  
         if (stat(tkt_string(), &st) < 0)  
                 return;  
   
         creds = xmalloc(sizeof(*creds));  
   
         problem = krb_get_tf_fullname(TKT_FILE, pname, pinst, prealm);  
         if (problem)  
                 goto out;  
   
         problem = krb_get_cred("krbtgt", prealm, prealm, creds);  
         if (problem)  
                 goto out;  
   
         if (time(0) > krb_life_to_time(creds->issue_date, creds->lifetime)) {  
                 problem = RD_AP_EXP;  
                 goto out;  
         }  
         creds_to_radix(creds, (u_char *)buffer, sizeof(buffer));  
   
         packet_start(SSH_CMSG_HAVE_KERBEROS_TGT);  
         packet_put_cstring(buffer);  
         packet_send();  
         packet_write_wait();  
   
         type = packet_read();  
   
         if (type == SSH_SMSG_SUCCESS)  
                 debug("Kerberos v4 TGT forwarded (%s%s%s@%s).",  
                     creds->pname, creds->pinst[0] ? "." : "",  
                     creds->pinst, creds->realm);  
         else  
                 debug("Kerberos v4 TGT rejected.");  
   
         xfree(creds);  
         return;  
   
  out:  
         debug("Kerberos v4 TGT passing failed: %s", krb_err_txt[problem]);  
         xfree(creds);  
 }  
   
 static void  
 send_afs_tokens(void)  
 {  
         CREDENTIALS creds;  
         struct ViceIoctl parms;  
         struct ClearToken ct;  
         int i, type, len;  
         char buf[2048], *p, *server_cell;  
         char buffer[8192];  
   
         /* Move over ktc_GetToken, here's something leaner. */  
         for (i = 0; i < 100; i++) {     /* just in case */  
                 parms.in = (char *) &i;  
                 parms.in_size = sizeof(i);  
                 parms.out = buf;  
                 parms.out_size = sizeof(buf);  
                 if (k_pioctl(0, VIOCGETTOK, &parms, 0) != 0)  
                         break;  
                 p = buf;  
   
                 /* Get secret token. */  
                 memcpy(&creds.ticket_st.length, p, sizeof(u_int));  
                 if (creds.ticket_st.length > MAX_KTXT_LEN)  
                         break;  
                 p += sizeof(u_int);  
                 memcpy(creds.ticket_st.dat, p, creds.ticket_st.length);  
                 p += creds.ticket_st.length;  
   
                 /* Get clear token. */  
                 memcpy(&len, p, sizeof(len));  
                 if (len != sizeof(struct ClearToken))  
                         break;  
                 p += sizeof(len);  
                 memcpy(&ct, p, len);  
                 p += len;  
                 p += sizeof(len);       /* primary flag */  
                 server_cell = p;  
   
                 /* Flesh out our credentials. */  
                 strlcpy(creds.service, "afs", sizeof(creds.service));  
                 creds.instance[0] = '\0';  
                 strlcpy(creds.realm, server_cell, REALM_SZ);  
                 memcpy(creds.session, ct.HandShakeKey, DES_KEY_SZ);  
                 creds.issue_date = ct.BeginTimestamp;  
                 creds.lifetime = krb_time_to_life(creds.issue_date,  
                     ct.EndTimestamp);  
                 creds.kvno = ct.AuthHandle;  
                 snprintf(creds.pname, sizeof(creds.pname), "AFS ID %d", ct.ViceId);  
                 creds.pinst[0] = '\0';  
   
                 /* Encode token, ship it off. */  
                 if (creds_to_radix(&creds, (u_char *)buffer,  
                     sizeof(buffer)) <= 0)  
                         break;  
                 packet_start(SSH_CMSG_HAVE_AFS_TOKEN);  
                 packet_put_cstring(buffer);  
                 packet_send();  
                 packet_write_wait();  
   
                 /* Roger, Roger. Clearance, Clarence. What's your vector,  
                    Victor? */  
                 type = packet_read();  
   
                 if (type == SSH_SMSG_FAILURE)  
                         debug("AFS token for cell %s rejected.", server_cell);  
                 else if (type != SSH_SMSG_SUCCESS)  
                         packet_disconnect("Protocol error on AFS token response: %d", type);  
         }  
 }  
   
 #endif /* AFS */  
   
 /*  /*
  * Tries to authenticate with any string-based challenge/response system.   * Tries to authenticate with any string-based challenge/response system.
  * Note that the client code is not tied to s/key or TIS.   * Note that the client code is not tied to s/key or TIS.
Line 1137 
Line 885 
         }          }
 #endif /* KRB5 */  #endif /* KRB5 */
   
 #ifdef KRB4  
         if ((supported_authentications & (1 << SSH_AUTH_KERBEROS)) &&  
             options.kerberos_authentication) {  
                 debug("Trying Kerberos v4 authentication.");  
   
                 if (try_krb4_authentication()) {  
                         type = packet_read();  
                         if (type == SSH_SMSG_SUCCESS)  
                                 goto success;  
                         if (type != SSH_SMSG_FAILURE)  
                                 packet_disconnect("Protocol error: got %d in response to Kerberos v4 auth", type);  
                 }  
         }  
 #endif /* KRB4 */  
   
         /*          /*
          * Use rhosts authentication if running in privileged socket and we           * Use rhosts authentication if running in privileged socket and we
          * do not wish to remain anonymous.           * do not wish to remain anonymous.
Line 1238 
Line 971 
         if (context)          if (context)
                 krb5_free_context(context);                  krb5_free_context(context);
 #endif  #endif
   
 #ifdef AFS  
         /* Try Kerberos v4 TGT passing if the server supports it. */  
         if ((supported_authentications & (1 << SSH_PASS_KERBEROS_TGT)) &&  
             options.kerberos_tgt_passing) {  
                 if (options.cipher == SSH_CIPHER_NONE)  
                         logit("WARNING: Encryption is disabled! Ticket will be transmitted in the clear!");  
                 send_krb4_tgt();  
         }  
         /* Try AFS token passing if the server supports it. */  
         if ((supported_authentications & (1 << SSH_PASS_AFS_TOKEN)) &&  
             options.afs_token_passing && k_hasafs()) {  
                 if (options.cipher == SSH_CIPHER_NONE)  
                         logit("WARNING: Encryption is disabled! Token will be transmitted in the clear!");  
                 send_afs_tokens();  
         }  
 #endif /* AFS */  
   
         return; /* need statement after label */          return; /* need statement after label */
 }  }

Legend:
Removed from v.1.53  
changed lines
  Added in v.1.54