This is auth-kerberos.c in view mode; [Download] [Up]
/* auth-kerberos.c Initally written by Dug Song <dugsong@umich.edu> for Kerberos V4. Mapped over to user Kerberos V5 by Glenn Machin - Sandia Natl Labs Kerberos authentication and ticket-passing routines. */ /* * $Id: auth-kerberos.c,v 1.3 1998/01/02 06:13:56 kivinen Exp $ * $Log: auth-kerberos.c,v $ * Revision 1.3 1998/01/02 06:13:56 kivinen * Fixed kerberos ticket allocation. * * Revision 1.2 1997/04/17 03:56:51 kivinen * Kept FILE: prefix in kerberos ticket filename as DCE cache * code requires it (patch from Doug Engert <DEEngert@anl.gov>). * * Revision 1.1 1997/03/27 03:09:29 kivinen * *** empty log message *** * * * $Endlog$ */ #include "includes.h" #include "packet.h" #include "xmalloc.h" #include "ssh.h" #ifdef KERBEROS #if defined (KRB5) #include <krb5.h> extern krb5_context ssh_context; extern krb5_auth_context auth_context; int auth_kerberos(char *server_user, krb5_data *auth, krb5_principal *client) { krb5_error_code problem; krb5_ticket *ticket; krb5_data reply; krb5_principal tkt_client; char *server = 0; memset(&reply, 0, sizeof(reply)); if (auth_context) krb5_auth_con_free(ssh_context, auth_context); auth_context = 0; krb5_auth_con_init(ssh_context, &auth_context); problem = krb5_auth_con_genaddrs(ssh_context, auth_context, packet_get_connection_in(), KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR); if (problem) { if (auth_context) { krb5_auth_con_free(ssh_context, auth_context); auth_context = 0; } log_msg("Kerberos ticket authentication of user %s failed: %s", server_user, error_message(problem)); debug("Kerberos krb5_auth_con_genaddrs (%s).", error_message(problem)); packet_send_debug("Kerberos krb5_auth_con_genaddrs: %s", error_message(problem)); return 0; } problem = krb5_rd_req(ssh_context, &auth_context, auth, NULL, NULL, NULL, &ticket); if (problem) { if (auth_context) { krb5_auth_con_free(ssh_context, auth_context); auth_context = 0; } log_msg("Kerberos ticket authentication of user %s failed: %s", server_user, error_message(problem)); debug("Kerberos V5 rd_req failed (%s).", error_message(problem)); packet_send_debug("Kerberos V5 krb5_rd_req: %s", error_message(problem)); return 0; } /* Verify from ticket that the server used was of the form host/system */ problem = krb5_unparse_name(ssh_context, ticket->server, &server); if (problem) { krb5_free_ticket(ssh_context, ticket); log_msg("Kerberos ticket authentication of user %s failed: %s", server_user, error_message(problem)); debug("Kerberos krb5_unparse_name failed (%s).", error_message(problem)); packet_send_debug("Kerberos krb5_unparse_name: %s", error_message(problem)); return 0; } if (strncmp(server, "host/", strlen("host/"))) { krb5_free_ticket(ssh_context, ticket); log_msg("Kerberos ticket authentication of user %s failed: invalid service name (%s)", server_user, server); debug("Kerberos invalid service name (%s).", server); packet_send_debug("Kerberos invalid service name (%s).", server); krb5_xfree(server); return 0; } krb5_xfree(server); /* Extract the users name from the ticket client principal */ problem = krb5_copy_principal(ssh_context, ticket->enc_part2->client, &tkt_client); krb5_free_ticket(ssh_context, ticket); if (problem) { log_msg("Kerberos ticket authentication of user %s failed: %s", server_user, error_message(problem)); debug("Kerberos krb5_copy_principal failed (%s).", error_message(problem)); packet_send_debug("Kerberos krb5_copy_principal: %s", error_message(problem)); return 0; } *client = tkt_client; /* Make the reply - so that mutual authentication can be done */ if ((problem = krb5_mk_rep(ssh_context, auth_context, &reply))) { log_msg("Kerberos ticket authentication of user %s failed: %s", server_user, error_message(problem)); debug("Kerberos krb5_mk_rep failed (%s).", error_message(problem)); packet_send_debug("Kerberos krb5_mk_rep failed: %s", error_message(problem)); return 0; } packet_start(SSH_SMSG_AUTH_KERBEROS_RESPONSE); packet_put_string((char *) reply.data, reply.length); packet_send(); packet_write_wait(); krb5_xfree(reply.data); return 1; } #endif /* KRB5 */ #endif /* KERBEROS */ #ifdef KERBEROS_TGT_PASSING #if defined (KRB5) int auth_kerberos_tgt( char *server_user, krb5_data *krb5data) { krb5_creds **creds; krb5_error_code retval; static char ccname[128]; krb5_ccache ccache = NULL; struct passwd *pwd; extern char *ticket; static krb5_principal rcache_server = 0; static krb5_rcache rcache; struct sockaddr_in local, foreign; krb5_address *local_addr, *remote_addr; int s; if (!(pwd = (struct passwd *) getpwnam(server_user))) { log_msg("Kerberos V5 tgt rejected for user %.100s", server_user); packet_send_debug("Kerberos V5 tgt rejected for %.100s", server_user); packet_start(SSH_SMSG_FAILURE); packet_send(); packet_write_wait(); return 0; } if (!auth_context) { if (!rcache_server) krb5_parse_name(ssh_context,"sshd", &rcache_server); krb5_auth_con_init(ssh_context, &auth_context); /* Set the addresses for local and remote systems, and replay cache */ /* GDM : We need to establish the local addresses and remote addresses within auth_context, in order to to TGT forwarding. Normally when the authentication credentials are passed, these are established then, however in SSH the forwarded TGT is passed prior to authentication. (Needed by AFS) */ s = packet_get_connection_in(); krb5_auth_con_genaddrs(ssh_context, auth_context, s, KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR | KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR); krb5_get_server_rcache(ssh_context, krb5_princ_component(context, rcache_server, 0), &rcache); krb5_auth_con_setrcache( ssh_context, auth_context, rcache); } if (retval = krb5_rd_cred(ssh_context, auth_context, krb5data, &creds, NULL)) { log_msg("Kerberos V5 tgt rejected for user %.100s : %s", server_user, error_message(retval)); packet_send_debug("Kerberos V5 tgt rejected for %.100s : %s", server_user, error_message(retval)); packet_start(SSH_SMSG_FAILURE); packet_send(); packet_write_wait(); return 0; } sprintf(ccname, "FILE:/tmp/krb5cc_p%d", getpid()); if (retval = krb5_cc_resolve(ssh_context, ccname, &ccache)) goto errout; if (retval = krb5_cc_initialize(ssh_context, ccache, (*creds)->client)) goto errout; if (retval = krb5_cc_store_cred(ssh_context, ccache, *creds)) goto errout; if (retval = chown(ccname+5, pwd->pw_uid, -1)) goto errout; ticket = xmalloc(strlen(ccname) + 1); (void) sprintf(ticket, "%s", ccname); /* Successful */ packet_start(SSH_SMSG_SUCCESS); packet_send(); packet_write_wait(); return 1; errout: krb5_free_tgt_creds(ssh_context, creds); log_msg("Kerberos V5 tgt rejected for user %.100s :%s", server_user, error_message(retval)); packet_send_debug("Kerberos V5 tgt rejected for %.100s : %s", server_user, error_message(retval)); packet_start(SSH_SMSG_FAILURE); packet_send(); packet_write_wait(); return 0; } #endif /* KRB5 */ #endif /* KERBEROS_TGT_PASSING */
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.