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); }
int Condor_Auth_Kerberos :: forward_tgt_creds(krb5_creds * cred, krb5_ccache ccache) { krb5_error_code code; krb5_data request; int message, rc = 1; MyString hostname; hostname = get_hostname(mySock_->peer_addr()); char* hostname_char = strdup(hostname.Value()); if ((code = krb5_fwd_tgt_creds(krb_context_, auth_context_, hostname_char, cred->client, cred->server, ccache, KDC_OPT_FORWARDABLE, &request))) { free(hostname_char); goto error; } free(hostname_char); // Now, send it message = KERBEROS_FORWARD; mySock_->encode(); if ((!mySock_->code(message)) || (!mySock_->end_of_message())) { dprintf(D_ALWAYS, "Failed to send KERBEROS_FORWARD response\n"); goto cleanup; } rc = !(send_request(&request) == KERBEROS_GRANT); goto cleanup; error: dprintf( D_ALWAYS, "KERBEROS: %s\n", error_message(code) ); cleanup: free(request.data); return rc; }
int auks_krb5_cred_get_fwd(char *ccachefilename, char *serverName, char **p_buffer, size_t * p_buffer_length) { int fstatus = AUKS_ERROR ; /* kerberos related variables */ krb5_error_code err_code; krb5_context context; krb5_ccache ccache; krb5_principal principal; krb5_creds **out_creds_array = NULL; krb5_auth_context auth_context; krb5_flags authopts; krb5_data outbuf; krb5_data *p_outbuf; krb5_replay_data krdata; authopts = AP_OPTS_MUTUAL_REQUIRED; authopts &= (~OPTS_FORWARD_CREDS); authopts &= (~OPTS_FORWARDABLE_CREDS); if ( serverName == NULL ) { auks_error("no host specified"); fstatus = AUKS_ERROR_KRB5_CRED_NO_HOST_SPECIFIED ; goto exit; } /* initialize kerberos context */ err_code = krb5_init_context(&context); if (err_code) { auks_error("unable to initialize kerberos context : %s", error_message(err_code)); fstatus = AUKS_ERROR_KRB5_CRED_INIT_CTX ; goto exit; } auks_log("kerberos context successfully initialized"); /* initialize kerberos credential cache structure */ if (ccachefilename == NULL) err_code = krb5_cc_default(context, &ccache); else err_code = krb5_cc_resolve(context,ccachefilename,&ccache); if (err_code) { auks_error("unable to resolve credential cache : %s", error_message(err_code)); fstatus = AUKS_ERROR_KRB5_CRED_OPEN_CC ; goto ctx_exit ; } auks_log("credential cache successfully resolved"); /* get principal using credential cache */ err_code = krb5_cc_get_principal(context,ccache,&principal); if (err_code) { auks_error("unable to get principal from credential cache : %s", error_message(err_code)); fstatus = AUKS_ERROR_KRB5_CRED_GET_PRINC ; goto cc_exit ; } auks_log("principal successfully extracted from credential cache"); /* initialize kerberos authentication context */ err_code = krb5_auth_con_init(context,&auth_context); if (err_code) { auks_error("unable to initialize kerberos authentication " "context : %s",error_message(err_code)); fstatus = AUKS_ERROR_KRB5_CRED_INIT_AUTH_CTX ; goto princ_exit; } auks_log("kerberos authentication context successfully initialized"); /* do replay detection using timestamps */ krb5_auth_con_setflags(context,auth_context,KRB5_AUTH_CONTEXT_RET_TIME); /* get forwarded credential for server */ err_code = krb5_fwd_tgt_creds(context,auth_context,serverName, principal,NULL,NULL,authopts,&outbuf); if (err_code) { auks_error("unable to get serialized and crypted forwarded " "credential for %s from KDC : %s", serverName,error_message(err_code)); fstatus = AUKS_ERROR_KRB5_CRED_GET_FWD_CRED ; goto auth_ctx_exit; } auks_log("serialized and crypted forwarded credential for %s " "successfully got from KDC",serverName); /* desactive replay detection */ krb5_auth_con_setflags(context,auth_context,0); /* decrypt (using session key stored in auth context) and */ /* unserialized forwarded credential in a kerberos credential */ /* structure */ err_code = krb5_rd_cred(context,auth_context,&outbuf,&out_creds_array, &krdata); if (err_code) { auks_error("unable to unserialize and decrypt forwarded " "credential for %s : %s",serverName, error_message(err_code)); fstatus = AUKS_ERROR_KRB5_CRED_RD_CRED ; goto fwd_exit; } auks_log("unserialization and decryption of forwarded " "credential for %s succesfully done",serverName); /* Reinitialize kerberos authentication context in order to */ /* write credential to output buffer */ krb5_auth_con_free(context,auth_context); err_code = krb5_auth_con_init(context,&auth_context); if (err_code) { auks_error("unable to reinitialize kerberos connection " "authentication context : %s",error_message (err_code)); fstatus = AUKS_ERROR_KRB5_CRED_INIT_AUTH_CTX ; goto rd_cred_exit; } auks_log("kerberos connection authentication context " "reinitialization successfully done"); /* no flags */ krb5_auth_con_setflags(context,auth_context,0); /* serialize forwarded credential (no encryption because auth */ /* context session key is nullified) */ err_code = krb5_mk_1cred(context,auth_context,*out_creds_array, &p_outbuf,&krdata); if (err_code) { auks_error("unable to serialize forwarded credential for " "%s : %s",serverName,error_message(err_code)); fstatus = AUKS_ERROR_KRB5_CRED_MK_CRED ; goto rd_cred_exit; } auks_log("forwarded credential for %s successfully serialized", serverName); /* allocate output buffer and store serialized credential */ (*p_buffer) = (char *) malloc(p_outbuf->length * sizeof(char)); if ((*p_buffer) == NULL) { auks_error("unable to allocate serialized credential output " "buffer for %s",serverName); *p_buffer_length = 0 ; fstatus = AUKS_ERROR_KRB5_CRED_MALLOC ; } else { /* copy data */ memcpy(*p_buffer,p_outbuf->data,p_outbuf->length); *p_buffer_length = p_outbuf->length; auks_log("forwarded credential successfully stored " "in output buffer"); fstatus = AUKS_SUCCESS ; } krb5_free_data(context,p_outbuf); rd_cred_exit: krb5_free_creds(context,*out_creds_array); free(out_creds_array); fwd_exit: krb5_free_data_contents(context, &outbuf); auth_ctx_exit: krb5_auth_con_free(context,auth_context); princ_exit: krb5_free_principal(context, principal); cc_exit: krb5_cc_close(context, ccache); ctx_exit: krb5_free_context(context); exit: return fstatus; }
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); }