📄 forward.c
字号:
/* * $Source: /cvsroot/inetutils/inetutils/libtelnet/forward.c,v $ * $Id: forward.c,v 1.3 2000/07/06 04:21:08 alainm Exp $ */#ifndef lintstatic char *rcsid_forward_c = "$Id: forward.c,v 1.3 2000/07/06 04:21:08 alainm Exp $";#endif /* lint */#define LIBC_SCCS/*- * Copyright (c) 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#ifndef lintstatic char sccsid[] = "@(#)forward.c 8.2 (Berkeley) 5/30/95";#endif /* not lint *//* General-purpose forwarding routines. These routines may be put into *//* libkrb5.a to allow widespread use */#if defined(KRB5) && defined(FORWARD)#include <stdio.h>#include <pwd.h>#include <netdb.h>#include <krb5/krb5.h>#include <krb5/asn1.h>#include <krb5/crc-32.h>#include <krb5/los-proto.h>#include <krb5/ext-proto.h>#define KRB5_DEFAULT_LIFE 60*60*8 /* 8 hours *//* helper function: convert flags to necessary KDC options */#define flags2options(flags) (flags & KDC_TKT_COMMON_MASK)/* Get a TGT for use at the remote host */krb5_error_codeget_for_creds(etype, sumtype, rhost, client, enc_key, forwardable, outbuf) const krb5_enctype etype; const krb5_cksumtype sumtype; char *rhost; krb5_principal client; krb5_keyblock *enc_key; int forwardable; /* Should forwarded TGT also be forwardable? */ krb5_data *outbuf;{ struct hostent *hp; krb5_address **addrs; krb5_error_code retval; krb5_data *scratch; krb5_kdc_rep *dec_rep; krb5_error *err_reply; krb5_response tgsrep; krb5_creds creds, tgt; krb5_ccache cc; krb5_flags kdcoptions; krb5_timestamp now; char *remote_host; char **hrealms; int i; if (!rhost || !(hp = gethostbyname(rhost))) return KRB5_ERR_BAD_HOSTNAME; remote_host = (char *) malloc(strlen(hp->h_name)+1); if (!remote_host) return ENOMEM; strcpy(remote_host, hp->h_name); if (retval = krb5_get_host_realm(remote_host, &hrealms)) { free(remote_host); return retval; } if (!hrealms[0]) { free(remote_host); krb5_xfree(hrealms); return KRB5_ERR_HOST_REALM_UNKNOWN; } /* Count elements */ for(i=0; hp->h_addr_list[i]; i++); addrs = (krb5_address **) malloc ((i+1)*sizeof(*addrs)); if (!addrs) return ENOMEM; for(i=0; hp->h_addr_list[i]; i++) { addrs[i] = (krb5_address *) malloc(sizeof(krb5_address)); if (addrs[i]) { addrs[i]->addrtype = hp->h_addrtype; addrs[i]->length = hp->h_length; addrs[i]->contents = (unsigned char *)malloc(addrs[i]->length); if (!addrs[i]->contents) { krb5_free_addresses(addrs); return ENOMEM; } else memmove ((char *)addrs[i]->contents, hp->h_addr_list[i], addrs[i]->length); } else { return ENOMEM; } } addrs[i] = 0; memset((char *)&creds, 0, sizeof(creds)); if (retval = krb5_copy_principal(client, &creds.client)) return retval; if (retval = krb5_build_principal_ext(&creds.server, strlen(hrealms[0]), hrealms[0], KRB5_TGS_NAME_SIZE, KRB5_TGS_NAME, client->realm.length, client->realm.data, 0)) return retval; creds.times.starttime = 0; if (retval = krb5_timeofday(&now)) { return retval; } creds.times.endtime = now + KRB5_DEFAULT_LIFE; creds.times.renew_till = 0; if (retval = krb5_cc_default(&cc)) { return retval; } /* fetch tgt directly from cache */ if (retval = krb5_cc_retrieve_cred (cc, KRB5_TC_MATCH_SRV_NAMEONLY, &creds, &tgt)) { return retval; } /* tgt->client must be equal to creds.client */ if (!krb5_principal_compare(tgt.client, creds.client)) return KRB5_PRINC_NOMATCH; if (!tgt.ticket.length) return(KRB5_NO_TKT_SUPPLIED); kdcoptions = flags2options(tgt.ticket_flags)|KDC_OPT_FORWARDED; if (!forwardable) /* Reset KDC_OPT_FORWARDABLE */ kdcoptions &= ~(KDC_OPT_FORWARDABLE); if (retval = krb5_send_tgs(kdcoptions, &creds.times, etype, sumtype, creds.server, addrs, creds.authdata, 0, /* no padata */ 0, /* no second ticket */ &tgt, &tgsrep)) return retval;#undef cleanup#define cleanup() free(tgsrep.response.data) switch (tgsrep.message_type) { case KRB5_TGS_REP: break; case KRB5_ERROR: default: if (!krb5_is_krb_error(&tgsrep.response)) { retval = KRB5KRB_AP_ERR_MSG_TYPE; } else retval = decode_krb5_error(&tgsrep.response, &err_reply); if (retval) { cleanup(); return retval; /* neither proper reply nor error! */ } retval = err_reply->error + ERROR_TABLE_BASE_krb5; krb5_free_error(err_reply); cleanup(); return retval; } retval = krb5_decode_kdc_rep(&tgsrep.response, &tgt.keyblock, etype, /* enctype */ &dec_rep); cleanup(); if (retval) return retval;#undef cleanup#define cleanup() {\ memset((char *)dec_rep->enc_part2->session->contents, 0,\ dec_rep->enc_part2->session->length);\ krb5_free_kdc_rep(dec_rep); } if (dec_rep->msg_type != KRB5_TGS_REP) { retval = KRB5KRB_AP_ERR_MSG_TYPE; cleanup(); return retval; } /* now it's decrypted and ready for prime time */ if (!krb5_principal_compare(dec_rep->client, tgt.client)) { cleanup(); return KRB5_KDCREP_MODIFIED; } if (retval = mk_cred(dec_rep, etype, enc_key, 0, 0, outbuf)) return retval; krb5_free_kdc_rep(dec_rep); return retval;#undef cleanup}/* Create asn.1 encoded KRB-CRED message from the kdc reply. */krb5_error_codemk_cred(dec_rep, etype, key, sender_addr, recv_addr, outbuf)krb5_kdc_rep *dec_rep;krb5_enctype etype;krb5_keyblock *key;krb5_address *sender_addr;krb5_address *recv_addr;krb5_data *outbuf;{ krb5_error_code retval; krb5_encrypt_block eblock; krb5_cred ret_cred; krb5_cred_enc_part cred_enc_part; krb5_data *scratch; if (!valid_etype(etype)) return KRB5_PROG_ETYPE_NOSUPP; ret_cred.tickets = (krb5_ticket **) calloc(2, sizeof(*ret_cred.tickets)); if (!ret_cred.tickets) return ENOMEM; ret_cred.tickets[0] = dec_rep->ticket; ret_cred.tickets[1] = 0; ret_cred.enc_part.etype = etype; ret_cred.enc_part.kvno = 0; cred_enc_part.ticket_info = (krb5_cred_info **) calloc(2, sizeof(*cred_enc_part.ticket_info)); if (!cred_enc_part.ticket_info) { krb5_free_tickets(ret_cred.tickets); return ENOMEM; } cred_enc_part.ticket_info[0] = (krb5_cred_info *) malloc(sizeof(*cred_enc_part.ticket_info[0])); if (!cred_enc_part.ticket_info[0]) { krb5_free_tickets(ret_cred.tickets); krb5_free_cred_enc_part(cred_enc_part); return ENOMEM; } cred_enc_part.nonce = 0; if (retval = krb5_us_timeofday(&cred_enc_part.timestamp, &cred_enc_part.usec)) return retval; cred_enc_part.s_address = (krb5_address *)sender_addr; cred_enc_part.r_address = (krb5_address *)recv_addr; cred_enc_part.ticket_info[0]->session = dec_rep->enc_part2->session; cred_enc_part.ticket_info[0]->client = dec_rep->client; cred_enc_part.ticket_info[0]->server = dec_rep->enc_part2->server; cred_enc_part.ticket_info[0]->flags = dec_rep->enc_part2->flags; cred_enc_part.ticket_info[0]->times = dec_rep->enc_part2->times; cred_enc_part.ticket_info[0]->caddrs = dec_rep->enc_part2->caddrs; cred_enc_part.ticket_info[1] = 0; /* start by encoding to-be-encrypted part of the message */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -