int kerberos5_is_forward (TN_Authenticator * ap, unsigned char *data, int cnt, char *errbuf, int errbuflen) { int r = 0; krb5_data inbuf; inbuf.length = cnt; inbuf.data = (char *) data; if ((r = krb5_auth_con_genaddrs (telnet_context, auth_context, net, KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR)) || (r = rd_and_store_for_creds (telnet_context, auth_context, &inbuf, ticket))) { snprintf (errbuf, errbuflen, "Read forwarded creds failed: %s", error_message (r)); Data (ap, KRB_FORWARD_REJECT, errbuf, -1); DEBUG (("Could not read forwarded credentials\r\n")); } else { Data (ap, KRB_FORWARD_ACCEPT, 0, 0); DEBUG (("Forwarded credentials obtained\r\n")); } return r; }
void kerberos5_forward(kstream ks) { krb5_error_code r; krb5_ccache ccache; krb5_principal client = 0; krb5_principal server = 0; krb5_data forw_creds; forw_creds.data = 0; if ((r = krb5_cc_default(k5_context, &ccache))) { com_err(NULL, r, "Kerberos V5: could not get default ccache"); return; } if ((r = krb5_cc_get_principal(k5_context, ccache, &client))) { com_err(NULL, r, "Kerberos V5: could not get default principal"); goto cleanup; } if ((r = krb5_sname_to_principal(k5_context, szHostName, KRB_SERVICE_NAME, KRB5_NT_SRV_HST, &server))) { com_err(NULL, r, "Kerberos V5: could not make server principal"); goto cleanup; } if ((r = krb5_auth_con_genaddrs(k5_context, auth_context, ks->fd, KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR))) { com_err(NULL, r, "Kerberos V5: could not gen local full address"); goto cleanup; } if (r = krb5_fwd_tgt_creds(k5_context, auth_context, 0, client, server, ccache, forwardable_flag, &forw_creds)) { com_err(NULL, r, "Kerberos V5: error getting forwarded creds"); goto cleanup; } /* Send forwarded credentials */ if (!Data(ks, KRB_FORWARD, forw_creds.data, forw_creds.length)) { MessageBox(HWND_DESKTOP, "Not enough room for authentication data", "", MB_OK | MB_ICONEXCLAMATION); } cleanup: if (client) krb5_free_principal(k5_context, client); if (server) krb5_free_principal(k5_context, server); #if 0 /* XXX */ if (forw_creds.data) free(forw_creds.data); #endif krb5_cc_close(k5_context, ccache); }
//---------------------------------------------------------------------- // Initialze some general structures for kerberos //---------------------------------------------------------------------- int Condor_Auth_Kerberos :: init_kerberos_context() { krb5_error_code code = 0; krb5_address ** localAddr = NULL; krb5_address ** remoteAddr = NULL; // kerberos context_ if (krb_context_ == NULL) { if ((code = krb5_init_context(&krb_context_))) { goto error; } } if ((code = krb5_auth_con_init(krb_context_, &auth_context_))) { goto error; } if ((code = krb5_auth_con_setflags(krb_context_, auth_context_, KRB5_AUTH_CONTEXT_DO_SEQUENCE))) { goto error; } if ((code = krb5_auth_con_genaddrs(krb_context_, auth_context_, mySock_->get_file_desc(), KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR| KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR ))) { goto error; } if ((code = krb5_auth_con_getaddrs(krb_context_, auth_context_, localAddr, remoteAddr))) { goto error; } // stash location defaultStash_ = param(STR_CONDOR_CACHE_DIR); if (defaultStash_ == NULL) { defaultStash_ = strdup(STR_DEFAULT_CONDOR_SPOOL); } return TRUE; error: dprintf( D_ALWAYS, "Unable to initialize kerberos: %s\n", error_message(code) ); return FALSE; }
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_auth_con_setaddrs_from_fd (krb5_context context, krb5_auth_context auth_context, void *p_fd) { krb5_socket_t fd = *(krb5_socket_t *)p_fd; int flags = 0; if(auth_context->local_address == NULL) flags |= KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR; if(auth_context->remote_address == NULL) flags |= KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR; return krb5_auth_con_genaddrs(context, auth_context, fd, flags); }
int do_krb5_login (int infd, struct auth_data *ap, const char **err_msg) { krb5_auth_context auth_ctx = NULL; krb5_error_code status; krb5_data inbuf; krb5_data version; krb5_authenticator *authenticator; krb5_rcache rcache; krb5_keyblock *key; krb5_ticket *ticket; struct sockaddr_in laddr; int len; struct passwd *pwd; char *name; if (status = krb5_init_context (&ap->context)) { syslog (LOG_ERR, "Error initializing krb5: %s", error_message (status)); return status; } if ((status = krb5_auth_con_init (ap->context, &auth_ctx)) || (status = krb5_auth_con_genaddrs (ap->context, auth_ctx, infd, KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR)) || (status = krb5_auth_con_getrcache (ap->context, auth_ctx, &rcache))) return status; if (!rcache) { krb5_principal server; status = krb5_sname_to_principal (ap->context, 0, 0, KRB5_NT_SRV_HST, &server); if (status) return status; status = krb5_get_server_rcache (ap->context, krb5_princ_component (ap->context, server, 0), &rcache); krb5_free_principal (ap->context, server); if (status) return status; status = krb5_auth_con_setrcache (ap->context, auth_ctx, rcache); if (status) return status; } len = sizeof (laddr); if (getsockname (infd, (struct sockaddr *) &laddr, &len)) return errno; status = krb5_recvauth (ap->context, &auth_ctx, &infd, NULL, 0, 0, ap->keytab, &ticket); if (status) return status; if ((status = krb5_auth_con_getauthenticator (ap->context, auth_ctx, &authenticator))) return status; getstr (infd, &ap->lusername, NULL); getstr (infd, &ap->term, "TERM="); pwd = getpwnam (ap->lusername); if (pwd == NULL) { *err_msg = "getpwnam failed"; syslog (LOG_ERR, "getpwnam failed: %m"); return 1; } getstr (infd, &ap->rusername, NULL); if ((status = krb5_copy_principal (ap->context, ticket->enc_part2->client, &ap->client))) return status; /*OK:: */ if (ap->client && !krb5_kuserok (ap->context, ap->client, ap->lusername)) return 1; krb5_unparse_name (ap->context, ap->client, &name); syslog (LOG_INFO | LOG_AUTH, "%sKerberos V login from %s on %s\n", (pwd->pw_uid == 0) ? "ROOT " : "", name, ap->hostname); free (name); return 0; }
static krb5_error_code change_password_loop (krb5_context context, krb5_creds *creds, krb5_principal targprinc, char *newpw, int *result_code, krb5_data *result_code_string, krb5_data *result_string, struct kpwd_proc *proc) { krb5_error_code ret; krb5_auth_context auth_context = NULL; krb5_krbhst_handle handle = NULL; krb5_krbhst_info *hi; int sock; int i; int done = 0; krb5_realm realm = creds->client->realm; ret = krb5_auth_con_init (context, &auth_context); if (ret) return ret; krb5_auth_con_setflags (context, auth_context, KRB5_AUTH_CONTEXT_DO_SEQUENCE); ret = krb5_krbhst_init (context, realm, KRB5_KRBHST_CHANGEPW, &handle); if (ret) goto out; while (!done && (ret = krb5_krbhst_next(context, handle, &hi)) == 0) { struct addrinfo *ai, *a; int is_stream; switch (hi->proto) { case KRB5_KRBHST_UDP: if ((proc->flags & SUPPORT_UDP) == 0) continue; is_stream = 0; break; case KRB5_KRBHST_TCP: if ((proc->flags & SUPPORT_TCP) == 0) continue; is_stream = 1; break; default: continue; } ret = krb5_krbhst_get_addrinfo(context, hi, &ai); if (ret) continue; for (a = ai; !done && a != NULL; a = a->ai_next) { int replied = 0; sock = socket (a->ai_family, a->ai_socktype, a->ai_protocol); if (sock < 0) continue; ret = connect(sock, a->ai_addr, a->ai_addrlen); if (ret < 0) { close (sock); goto out; } ret = krb5_auth_con_genaddrs (context, auth_context, sock, KRB5_AUTH_CONTEXT_GENERATE_LOCAL_ADDR); if (ret) { close (sock); goto out; } for (i = 0; !done && i < 5; ++i) { fd_set fdset; struct timeval tv; if (!replied) { replied = 0; ret = (*proc->send_req) (context, &auth_context, creds, targprinc, is_stream, sock, newpw, hi->hostname); if (ret) { close(sock); goto out; } } if (sock >= FD_SETSIZE) { krb5_set_error_string(context, "fd %d too large", sock); ret = ERANGE; close (sock); goto out; } FD_ZERO(&fdset); FD_SET(sock, &fdset); tv.tv_usec = 0; tv.tv_sec = 1 + (1 << i); ret = select (sock + 1, &fdset, NULL, NULL, &tv); if (ret < 0 && errno != EINTR) { close(sock); goto out; } if (ret == 1) { ret = (*proc->process_rep) (context, auth_context, is_stream, sock, result_code, result_code_string, result_string, hi->hostname); if (ret == 0) done = 1; else if (i > 0 && ret == KRB5KRB_AP_ERR_MUT_FAIL) replied = 1; } else { ret = KRB5_KDC_UNREACH; } } close (sock); } } out: krb5_krbhst_free (context, handle); krb5_auth_con_free (context, auth_context); if (done) return 0; else { if (ret == KRB5_KDC_UNREACH) { krb5_set_error_string(context, "unable to reach any changepw server " " in realm %s", realm); *result_code = KRB5_KPASSWD_HARDERROR; } return ret; } }
static krb5_error_code recvauth(int f, krb5_context krb_context, unsigned int *valid_checksum, krb5_ticket **ticket, int *auth_type, krb5_principal *client, int encr_flag, krb5_keytab keytab) { krb5_error_code status = 0; krb5_auth_context auth_context = NULL; krb5_rcache rcache; krb5_authenticator *authenticator; krb5_data inbuf; krb5_data auth_version; *valid_checksum = 0; if ((status = krb5_auth_con_init(krb_context, &auth_context))) return (status); /* Only need remote address for rd_cred() to verify client */ if ((status = krb5_auth_con_genaddrs(krb_context, auth_context, f, KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR))) return (status); status = krb5_auth_con_getrcache(krb_context, auth_context, &rcache); if (status) return (status); if (!rcache) { krb5_principal server; status = krb5_sname_to_principal(krb_context, 0, 0, KRB5_NT_SRV_HST, &server); if (status) return (status); status = krb5_get_server_rcache(krb_context, krb5_princ_component(krb_context, server, 0), &rcache); krb5_free_principal(krb_context, server); if (status) return (status); status = krb5_auth_con_setrcache(krb_context, auth_context, rcache); if (status) return (status); } if ((status = krb5_compat_recvauth(krb_context, &auth_context, &f, NULL, /* Specify daemon principal */ 0, /* no flags */ keytab, /* NULL to use v5srvtab */ ticket, /* return ticket */ auth_type, /* authentication system */ &auth_version))) { if (*auth_type == KRB5_RECVAUTH_V5) { /* * clean up before exiting */ getstr(f, rusername, sizeof (rusername), "remuser"); getstr(f, lusername, sizeof (lusername), "locuser"); getstr(f, term, sizeof (term), "Terminal type"); } return (status); } getstr(f, lusername, sizeof (lusername), "locuser"); getstr(f, term, sizeof (term), "Terminal type"); kcmd_protocol = KCMD_UNKNOWN_PROTOCOL; if (auth_version.length != 9 || auth_version.data == NULL) { syslog(LOG_ERR, "Bad application protocol version length in " "KRB5 exchange, exiting"); fatal(f, "Bad application version length, exiting."); } /* * Determine which Kerberos CMD protocol was used. */ if (strncmp(auth_version.data, "KCMDV0.1", 9) == 0) { kcmd_protocol = KCMD_OLD_PROTOCOL; } else if (strncmp(auth_version.data, "KCMDV0.2", 9) == 0) { kcmd_protocol = KCMD_NEW_PROTOCOL; } else { syslog(LOG_ERR, "Unrecognized KCMD protocol (%s), exiting", (char *)auth_version.data); fatal(f, "Unrecognized KCMD protocol, exiting"); } if ((*auth_type == KRB5_RECVAUTH_V5) && chksum_flag && kcmd_protocol == KCMD_OLD_PROTOCOL) { if ((status = krb5_auth_con_getauthenticator(krb_context, auth_context, &authenticator))) return (status); if (authenticator->checksum) { struct sockaddr_storage adr; int adr_length = sizeof (adr); int buflen; krb5_data input; krb5_keyblock key; char *chksumbuf; /* * Define the lenght of the chksum buffer. * chksum string = "[portnum]:termstr:username" * The extra 32 is to hold a integer string for * the portnumber. */ buflen = strlen(term) + strlen(lusername) + 32; chksumbuf = (char *)malloc(buflen); if (chksumbuf == 0) { krb5_free_authenticator(krb_context, authenticator); fatal(f, "Out of memory error"); } if (getsockname(f, (struct sockaddr *)&adr, &adr_length) != 0) { krb5_free_authenticator(krb_context, authenticator); fatal(f, "getsockname error"); } (void) snprintf(chksumbuf, buflen, "%u:%s%s", ntohs(SOCK_PORT(adr)), term, lusername); input.data = chksumbuf; input.length = strlen(chksumbuf); key.contents = (*ticket)->enc_part2->session->contents; key.length = (*ticket)->enc_part2->session->length; status = krb5_c_verify_checksum(krb_context, &key, 0, &input, authenticator->checksum, valid_checksum); if (status == 0 && *valid_checksum == 0) status = KRB5KRB_AP_ERR_BAD_INTEGRITY; if (chksumbuf) krb5_xfree(chksumbuf); if (status) { krb5_free_authenticator(krb_context, authenticator); return (status); } } krb5_free_authenticator(krb_context, authenticator); } if ((status = krb5_copy_principal(krb_context, (*ticket)->enc_part2->client, client))) return (status); /* Get the Unix username of the remote user */ getstr(f, rusername, sizeof (rusername), "remuser"); /* Get the Kerberos principal name string of the remote user */ if ((status = krb5_unparse_name(krb_context, *client, &krusername))) return (status); #ifdef DEBUG syslog(LOG_DEBUG | LOG_AUTH, "rlogind: got krb5 credentials for %s", (krusername != NULL ? krusername : "******")); #endif if (encr_flag) { status = krb5_auth_con_getremotesubkey(krb_context, auth_context, &session_key); if (status) { syslog(LOG_ERR, "Error getting KRB5 session " "subkey, exiting"); fatal(f, "Error getting KRB5 session subkey, exiting"); } /* * The "new" protocol requires that a subkey be sent. */ if (session_key == NULL && kcmd_protocol == KCMD_NEW_PROTOCOL) { syslog(LOG_ERR, "No KRB5 session subkey sent, exiting"); fatal(f, "No KRB5 session subkey sent, exiting"); } /* * The "old" protocol does not permit an authenticator subkey. * The key is taken from the ticket instead (see below). */ if (session_key != NULL && kcmd_protocol == KCMD_OLD_PROTOCOL) { syslog(LOG_ERR, "KRB5 session subkey not permitted " "with old KCMD protocol, exiting"); fatal(f, "KRB5 session subkey not permitted " "with old KCMD protocol, exiting"); } /* * If no key at this point, use the session key from * the ticket. */ if (session_key == NULL) { /* * Save the session key so we can configure the crypto * module later. */ status = krb5_copy_keyblock(krb_context, (*ticket)->enc_part2->session, &session_key); if (status) { syslog(LOG_ERR, "krb5_copy_keyblock failed"); fatal(f, "krb5_copy_keyblock failed"); } } /* * If session key still cannot be found, we must * exit because encryption is required here * when encr_flag (-x) is set. */ if (session_key == NULL) { syslog(LOG_ERR, "Could not find an encryption key," "exiting"); fatal(f, "Encryption required but key not found, " "exiting"); } } /* * Use krb5_read_message to read the principal stuff. */ if ((status = krb5_read_message(krb_context, (krb5_pointer)&f, &inbuf))) fatal(f, "Error reading krb5 message"); if (inbuf.length) { /* Forwarding being done, read creds */ krb5_creds **creds = NULL; if (status = krb5_rd_cred(krb_context, auth_context, &inbuf, &creds, NULL)) { if (rcache) (void) krb5_rc_close(krb_context, rcache); krb5_free_creds(krb_context, *creds); fatal(f, "Can't get forwarded credentials"); } /* Store the forwarded creds in the ccache */ if (status = store_forw_creds(krb_context, creds, *ticket, lusername, &ccache)) { if (rcache) (void) krb5_rc_close(krb_context, rcache); krb5_free_creds(krb_context, *creds); fatal(f, "Can't store forwarded credentials"); } krb5_free_creds(krb_context, *creds); } if (rcache) (void) krb5_rc_close(krb_context, rcache); return (status); }
static krb5_error_code chgpw_prexmit(krb5_context context, int proto, void *ctx, rk_socket_t fd, krb5_data *data) { struct request *request = ctx; krb5_data ap_req_data, krb_priv_data, passwd_data; krb5_storage *sp = NULL; krb5_error_code ret; krb5_ssize_t slen; size_t len; krb5_data_zero(&ap_req_data); krb5_data_zero(&krb_priv_data); ret = krb5_auth_con_genaddrs(context, request->ac, fd, KRB5_AUTH_CONTEXT_GENERATE_LOCAL_ADDR); if (ret) goto out; ret = krb5_mk_req_extended(context, &request->ac, AP_OPTS_MUTUAL_REQUIRED | AP_OPTS_USE_SUBKEY, NULL, request->creds, &ap_req_data); if (ret) goto out; passwd_data.data = rk_UNCONST(request->password); passwd_data.length = strlen(request->password); ret = krb5_mk_priv(context, request->ac, &passwd_data, &krb_priv_data, NULL); if (ret) goto out; sp = krb5_storage_emem(); if (sp == NULL) { ret = ENOMEM; goto out; } len = 6 + ap_req_data.length + krb_priv_data.length; ret = krb5_store_uint16(sp, len); if (ret) goto out; ret = krb5_store_uint16(sp, 1); if (ret) goto out; ret = krb5_store_uint16(sp, ap_req_data.length); if (ret) goto out; slen = krb5_storage_write(sp, ap_req_data.data, ap_req_data.length); if (slen != ap_req_data.length) { ret = EINVAL; goto out; } slen = krb5_storage_write(sp, krb_priv_data.data, krb_priv_data.length); if (slen != krb_priv_data.length) { ret = EINVAL; goto out; } ret = krb5_storage_to_data(sp, data); out: if (ret) _krb5_debugx(context, 10, "chgpw_prexmit failed with: %d", ret); if (sp) krb5_storage_free(sp); krb5_data_free(&krb_priv_data); krb5_data_free(&ap_req_data); return ret; }
static krb5_error_code setpw_prexmit(krb5_context context, int proto, void *ctx, int fd, krb5_data *data) { struct request *request = ctx; krb5_data ap_req_data, krb_priv_data, pwd_data; krb5_error_code ret; ChangePasswdDataMS chpw; krb5_storage *sp = NULL; ssize_t slen; size_t len; krb5_data_zero(&ap_req_data); krb5_data_zero(&krb_priv_data); krb5_data_zero(&pwd_data); ret = krb5_auth_con_genaddrs(context, request->ac, fd, KRB5_AUTH_CONTEXT_GENERATE_LOCAL_ADDR); if (ret) goto out; ret = krb5_mk_req_extended(context, &request->ac, AP_OPTS_MUTUAL_REQUIRED | AP_OPTS_USE_SUBKEY, NULL, request->creds, &ap_req_data); if (ret) goto out; chpw.newpasswd.length = strlen(request->password); chpw.newpasswd.data = rk_UNCONST(request->password); if (request->target) { chpw.targname = &request->target->name; chpw.targrealm = &request->target->realm; } else { chpw.targname = NULL; chpw.targrealm = NULL; } ASN1_MALLOC_ENCODE(ChangePasswdDataMS, pwd_data.data, pwd_data.length, &chpw, &len, ret); if (ret) goto out; if(pwd_data.length != len) krb5_abortx(context, "internal error in ASN.1 encoder"); ret = krb5_mk_priv (context, request->ac, &pwd_data, &krb_priv_data, NULL); if (ret) goto out; sp = krb5_storage_emem(); if (sp == NULL) { ret = ENOMEM; goto out; } len = 6 + ap_req_data.length + krb_priv_data.length; ret = krb5_store_uint16(sp, len); if (ret) goto out; ret = krb5_store_uint16(sp, 0xff80); if (ret) goto out; ret = krb5_store_uint16(sp, ap_req_data.length); if (ret) goto out; slen = krb5_storage_write(sp, ap_req_data.data, ap_req_data.length); if (slen != ap_req_data.length) { ret = EINVAL; goto out; } slen = krb5_storage_write(sp, krb_priv_data.data, krb_priv_data.length); if (slen != krb_priv_data.length) { ret = EINVAL; goto out; } ret = krb5_storage_to_data(sp, data); out: if (ret) _krb5_debugx(context, 10, "setpw_prexmit failed with %d", ret); if (sp) krb5_storage_free(sp); krb5_data_free(&krb_priv_data); krb5_data_free(&ap_req_data); krb5_data_free(&pwd_data); return ret; }
/* * Try krb5 authentication. server_user is passed for logging purposes * only, in auth is received ticket, in client is returned principal * from the ticket */ int auth_krb5(Authctxt *authctxt, krb5_data *auth, char **client) { krb5_error_code problem; krb5_principal server; krb5_data reply; krb5_ticket *ticket; int fd, ret; ret = 0; server = NULL; ticket = NULL; reply.length = 0; problem = krb5_init(authctxt); if (problem) goto err; problem = krb5_auth_con_init(authctxt->krb5_ctx, &authctxt->krb5_auth_ctx); if (problem) goto err; fd = packet_get_connection_in(); #ifdef HEIMDAL problem = krb5_auth_con_setaddrs_from_fd(authctxt->krb5_ctx, authctxt->krb5_auth_ctx, &fd); #else problem = krb5_auth_con_genaddrs(authctxt->krb5_ctx, authctxt->krb5_auth_ctx,fd, KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR | KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR); #endif if (problem) goto err; problem = krb5_sname_to_principal(authctxt->krb5_ctx, NULL, NULL , KRB5_NT_SRV_HST, &server); if (problem) goto err; problem = krb5_rd_req(authctxt->krb5_ctx, &authctxt->krb5_auth_ctx, auth, server, NULL, NULL, &ticket); if (problem) goto err; #ifdef HEIMDAL problem = krb5_copy_principal(authctxt->krb5_ctx, ticket->client, &authctxt->krb5_user); #else problem = krb5_copy_principal(authctxt->krb5_ctx, ticket->enc_part2->client, &authctxt->krb5_user); #endif if (problem) goto err; /* if client wants mutual auth */ problem = krb5_mk_rep(authctxt->krb5_ctx, authctxt->krb5_auth_ctx, &reply); if (problem) goto err; /* Check .k5login authorization now. */ if (!krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user, authctxt->pw->pw_name)) goto err; if (client) krb5_unparse_name(authctxt->krb5_ctx, authctxt->krb5_user, client); packet_start(SSH_SMSG_AUTH_KERBEROS_RESPONSE); packet_put_string((char *) reply.data, reply.length); packet_send(); packet_write_wait(); ret = 1; err: if (server) krb5_free_principal(authctxt->krb5_ctx, server); if (ticket) krb5_free_ticket(authctxt->krb5_ctx, ticket); if (reply.length) xfree(reply.data); if (problem) { if (authctxt->krb5_ctx != NULL) debug("Kerberos v5 authentication failed: %s", krb5_get_err_text(authctxt->krb5_ctx, problem)); else debug("Kerberos v5 authentication failed: %d", problem); } return (ret); }
void kerberos5_forward (TN_Authenticator * ap) { krb5_error_code r; krb5_ccache ccache; krb5_principal client = 0; krb5_principal server = 0; krb5_data forw_creds; forw_creds.data = 0; if ((r = krb5_cc_default (telnet_context, &ccache))) { DEBUG (("Kerberos V5: could not get default ccache - %s\r\n", error_message (r))); return; } for (;;) /* Fake loop */ { if ((r = krb5_cc_get_principal (telnet_context, ccache, &client))) { DEBUG (("Kerberos V5: could not get default principal - %s\r\n", error_message (r))); break; } if ((r = krb5_sname_to_principal (telnet_context, RemoteHostName, "host", KRB5_NT_SRV_HST, &server))) { DEBUG (("Kerberos V5: could not make server principal - %s\r\n", error_message (r))); break; } if ((r = krb5_auth_con_genaddrs (telnet_context, auth_context, net, KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR))) { DEBUG (("Kerberos V5: could not gen local full address - %s\r\n", error_message (r))); break; } if ((r = krb5_fwd_tgt_creds (telnet_context, auth_context, 0, client, server, ccache, forward_flags & OPTS_FORWARDABLE_CREDS, &forw_creds))) { DEBUG (("Kerberos V5: error getting forwarded creds - %s\r\n", error_message (r))); break; } /* Send forwarded credentials */ if (!Data (ap, KRB_FORWARD, forw_creds.data, forw_creds.length)) { DEBUG (("Not enough room for authentication data\r\n")); } else { DEBUG (("Forwarded local Kerberos V5 credentials to server\r\n")); } break; } if (client) krb5_free_principal (telnet_context, client); if (server) krb5_free_principal (telnet_context, server); free (forw_creds.data); krb5_cc_close (telnet_context, ccache); }